{
"messageshow": [
{
"message_id": "497",
"message": "http://flur.p-sites.info/api/messages/voice/1360076234.caff",
"message_pic": "<UIImage: 0xa29e160>",
"uid": "44",
"created": "4 hours ago",
"username": "pari",
"first_name": "pp",
"last_name": "pp",
"profile_pic": "http://flur.p-sites.info/api/uploads/13599968121.jpg",
"tag_user": {
"tags": [
{
"message": "false"
}
]
},
"boos_list": {
"booslist": [
{
"message": "false"
}
]
},
"aplouds_list": {
"aploudslist": [
{
"message": "false"
}
]
},
"total_comments": 0,
"total_boos": 0,
"total_applouds": 0
},
{
"message_id": "496",
"message": "http://flur.p-sites.info/api/messages/voice/1360076182.caff",
"message_pic": "<UIImage: 0xa3b0610>",
"uid": "44",
"created": "4 hours ago",
"username": "pari",
"first_name": "pp",
"last_name": "pp",
"profile_pic": "http://flur.p-sites.info/api/uploads/13599968121.jpg",
"tag_user": {
"tags": [
{
"message": "false"
}
]
},
"boos_list": {
"booslist": [
{
"message": "false"
}
]
},
"aplouds_list": {
"aploudslist": [
{
"message": "false"
}
]
},
"total_comments": 0,
"total_boos": 0,
"total_applouds": 0
}
]
}
In this JSON all value are coming in "" quotes, but few tags are coming without any quotes what does it indicate ?
JSON Display value without quote it consider as Numeric value..
For JSON beginner :
JSON Syntax Rules
JSON syntax is a subset of the JavaScript object notation syntax:
Data is in name/value pairs
Data is separated by commas
Curly braces hold objects
Square brackets hold arrays
JSON data is written as name/value pairs.
A name/value pair consists of a field name (in double quotes), followed by a colon, followed by a value:
"firstName" : "John"
This is simple to understand, and equals to the JavaScript statement:
firstName = "John"
JSON values can be:
A number (integer or floating point)
A string (in double quotes)
A Boolean (true or false)
An array (in square brackets)
An object (in curly brackets)
null
JSON Objects :
JSON objects are written inside curly brackets,
Objects can contain multiple name/values pairs:
{ "firstName":"John" , "lastName":"Doe" }
This is also simple to understand, and equals to the JavaScript statements:
firstName = "John"
lastName = "Doe"
JSON Arrays :
JSON arrays are written inside square brackets.
An array can contain multiple objects:
{
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}
In the example above, the object "employees" is an array containing three objects. Each object is a record of a person (with a first name and a last name).
This is Basic of JSON
For more understanding refere this site.
Thanks
The tags which are without double quotes are integer values or Boolean Values or NULL.
The tags which are starting with [] square brackets are Arrays.
The tags which are starting with {} is JSON inside a attribute/value.
That depends on the type of the value. If the value is an numerical type its WITHOUT the quotes.
If it is no numerical type it's WITH the quotes (for example Strings, like most in your example).
In addition to strings JSON supports numerical values. So in this case the values without quotes are simply considered numbers.
They are numeric values. As per the JSON docs:
A value can be a string in double quotes, or a number, or true or
false or null, or an object or an array. These structures can be
nested.
Related
I have a mongo database with a collection of countries.
One property (currencies) contains an array of currencies.
A currency has multiple properties:
"currencies": [{
"code": "EUR",
"name": "Euro",
"symbol": "€"
}],
I wish to select all countries who use Euro's besides other currencies.
I'm using the following statement:
db.countries.find({currencies: { $in: [{code: "EUR"}]}})
Unfortunately I'm getting an empty result set.
When I use:
db.countries.find({"currencies.code": "EUR"})
I do get results. Why is the first query not working and the second one succesfull?
The first query is not working as it checks whether the whole currency array is in the array, which is never true.
It is true when:
currencies: {
$in: [
[{
"code": "EUR",
"name": "Euro",
"symbol": "€"
}],
...
]
}
I believe that $elemMatch is what you need besides the dot notation.
db.collection.find({
currencies: {
$elemMatch: {
code: "EUR"
}
}
})
Sample Mongo Playground
MongoDB works in the same way if the query field is an array or a single value, that's why the second one works.
So why the first one doesn't work? The problem here is that you are looking for an object that is exactly defined as {code: "EUR"}: no name or symbol field are specified. To make it work, you should change it to:
db.getCollection('countries').find({currencies: { $in: [{
"code" : "EUR",
"name" : "Euro",
"symbol" : "€"
}]}})
or query the subfield directly:
db.getCollection('stuff').find({"currencies.code": { $in: ["EUR"]}})
Knows somebody, how to query from MongoDB value from this (JSON valid, pretty printed) object:
var a = JSON.parse(`
{
"vnut_okraj_podmienky": {
"": {
"standart_podmienky": {
"type": "radio",
"value": "on"
},
"nestand_teplota": {
"type": "number",
"value": "24"
},
"nestand_vlhkost": {
"type": "number",
"value": "70"
}
}
}
}
`
In browser console I can obtain value (=24) of:
a.vnut_okraj_podmienky[""].nestand_teplota.value
but mongosh returns [] on this (db name irrelevant):
db.isover_projects.distinct("vnut_okraj_podmienky.''.nestand_teplota.value")
and error MongoServerError: FieldPath field names may not be empty strings.
on:
db.isover_projects.distinct("vnut_okraj_podmienky..nestand_teplota.value")
The MongoDB server stores data in BSON.
According the specification at https://bsonspec.org/spec.html a field name must be
Zero or more modified UTF-8 encoded characters followed by '\x00'. The (byte*) MUST NOT contain '\x00', hence it is not full UTF-8.
So it technically can store the empty string as a field name.
This works in simple queries as well:
>db.collection.find({"":{a:1}})
[ { _id: ObjectId("616c4783e3be8ecf36d5e932"), '': { a: 1 } } ]
This also works dotted notation:
>db.collection.find({".a":1})
[ { _id: ObjectId("616c4783e3be8ecf36d5e932"), '': { a: 1 } } ]
However, that does not work if you try to use that empty field name with update, projection, or aggregation operators:
>db.collection.aggregate([{$match:{".a":1}},{$set:{".b":2}}])
MongoError: Invalid $set :: caused by :: FieldPath field names may not be empty strings.
So while it is technically permitted to store a document with a field whose name is the empty string, not all operations are support on such fields.
Using wiremock-standalone (version 2.29.1), I want to verify a request with its body holding an array of objects, containing optional properties.
For instance, consider this request:
Request body (JSON format)
{
"foo": [
{ "bar": "1" },
{ "qux": "oh hai" },
{ "bar": "ohnoes" }
]
}
And let's say I want to match requests only if all the foo.bar attributes are either present, or contain only a single digit (it's only for the sake of example). The example above should not match (the third object has a bar attributes with non-digits characters).
I tried different approches, and the closest I got is this:
{
"matchesJsonPath": {
"expression": "$.foo[*].bar",
"or": [
{ "matches": "^\\d$" },
{ "absent": true }
]
}
}
There are 2 problems:
if there is no bar attribute at all, the request does not match
if at least 1 bar attribute passes the check, then the whole request passes, even though other bar values are invalid (the example above passes)
Does anyone know how to create such a rule in wiremock?
I found a possible solution, maybe not the easiest but it works.
Following your example:
request:
{
"foo": [
{ "bar": "1" },
{ "qux": "oh hai" },
{ "bar": "ohnoes" }
]
}
This bodyPatterns file works for validate each field is present and it has the value given:
"bodyPatterns" : [
{
"matchesJsonPath": "$.foo[?(#.bar == '1')]"
},
{
"matchesJsonPath": "$.foo[?(#.qux == 'oh hai')]"
},
{
"matchesJsonPath": "$.foo[?(#.bar == 'ohnoes')]"
}
]
For reference, the following post helped me a lot:
Wiremock matchesJsonPath checking array values ignoring the order
I was going through the Postgres Jsonb documentation but was unable to find a solution for a small issue I'm having.
I've got a table : MY_TABLE
that has the following columns:
User, Name, Data and Purchased
One thing to note is that "Data" is a jsonb and has multiple fields. One of the fields inside of "Data" is "Attribute" but the values it can hold are not in sync. What I mean is, it could be a string, a list of strings, an empty list, or just an empty string. However, I want to change this.
The only values that I want to allow are a list of strings and an empty list. I want to convert all the empty strings to empty lists and regular strings to a list of strings.
I have tried using json_build_array but have not had any luck
So for example, I'd want my final jsonb to look like :
[{
"Id": 1,
"Attributes": ["Test"]
},
{
"Id": 2,
"Attributes": []
},
{
"Id": 3,
"Attributes": []
}]
when converted from
{
"Id": 1,
"Attributes": "Test"
},
{
"Id": 2,
"Attributes": ""
},
{
"Id": 3,
"Attributes": []
}
]
I only care about the "Attributes" field inside of the Json, not any other fields.
I also want to ensure for some Attributes that have an empty string "Attributes": "", they get mapped to an empty list and not a list with an empty string ([] not [""])
I also want to preserve the empty array values ([]) for the Attributes that already hold an empty array value.
This is what I have so far:
jsonb_set(
mycol,
'{Attributes}',
case when js ->> 'Attributes' <> ''
then jsonb_build_array(js ->> 'Attributes')
else '[]'::jsonb
end
)
However, Attributes: [] is getting mapped to ["[]"]
Use jsonb_array_elements() to iterate over the elements of each 'data' cell and jsonb_agg to regroup the transform values together into an array:
WITH test_data(js) AS (
VALUES ($$ [
{
"Id": 1,
"Attributes": "Test"
},
{
"Id": 2,
"Attributes": ""
},
{
"Id": 3,
"Attributes": []
}
]
$$::JSONB)
)
SELECT transformed_elem
FROM test_data
JOIN LATERAL (
SELECT jsonb_agg(jsonb_set(
elem,
'{Attributes}',
CASE
WHEN elem -> 'Attributes' IN ('""', '[]') THEN '[]'::JSONB
WHEN jsonb_typeof(elem -> 'Attributes') = 'string' THEN jsonb_build_array(elem -> 'Attributes')
ELSE elem -> 'Attributes'
END
)) AS transformed_elem
FROM jsonb_array_elements(test_data.js) AS f(elem) -- iterate over every element in the array
) s
ON TRUE
returns
[{"Id": 1, "Attributes": ["Test"]}, {"Id": 2, "Attributes": []}, {"Id": 3, "Attributes": []}]
I am trying to update a nested document in MongoDB that looks similar to below (shortened to be concise).
{
"cols": "20",
"saveTime": "2014-06-15-10:44:09",
"rows": "20",
"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8",
"players": [
{
"id": "Inhuman",
"num": "1",
"color": "00ff00ff",
"name": "badComputer",
"type": "1"
},
<...>
],
"nodes": [
{
"g": "1",
"c": "0",
"r": "0",
"a": "0",
"o": ""
},
{
"g": "1",
"c": "0",
"r": "1",
"a": "0",
"o": ""
}
<...>
],
}
What I am trying to do is update one of the nodes. For example, I want to change the node:
{ "g": "1", "c": "0", "r": "0", "a": "0", "o": ""}
to
{ "g": "1", "c": "0", "r": "0", "a": "5", "o": ""}
I have tried using the dot (.) notation, with the $set command, ala:
db.game.update({"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8"}, { $set: {"nodes.r":"0", "nodes.c":"0", "nodes.a":"5"}}),
But that does not give me the expected behavior because I'm updating all nodes with the same r and c values. This is obviously not what I want, but I do not see how to update a specific piece of this document. Does anyone have any idea how to do this?
If you are looking to update a specific item in your "nodes" array that you do not know the position of but you know the "criteria" to match that item, then you need the $elemMatch operator along with the positional $ operator in the update side:
db.game.update(
{
"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8",
"nodes": { "$elemMatch": { "g": 1, "r": 0 } }
},
{ "$set": { "nodes.$.c":"0", "nodes.$.a":"5" } }
)
The positional $ operator contains the matched "index" position of the first element "matched" by your query conditions. If you do not use $elemMatch and use the "dot notation" form instead, then the match is only valid for the whole document containing values that would be true and does not reflect the "position" of the element that matches both of the field conditions.
Care must be taken that this is the "first" match, and typically expected as the only match. The reason being that the positional operator will only contain the "first" position where there were multiple matches. To update more than one array item matching the criteria in this way, then you need to issue the update several times until the document is no longer modified.
For a "known" position you can always directly use the "dot notation" form, including the position of the element that you wish to update:
db.game.update(
{
"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8",
},
{ "$set": { "nodes.0.c":"0", "nodes.0.a":"5" } }
)
So the index position is 0 for the first element, 1 for the second element and so on.
Noting that in both cases, you only need to pass to $set the fields you actually want to change. So unless you are unsure of a value being present ( which would not be the case if that was your query ) then you do not need to "set" fields to the value they already contain.
To update specific node - you would need to put that in the query part of your search.
As in
db.game.update({"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8","nodes.r":"0",
"nodes.c":"0", "nodes.a":"5" }, { $set: {"nodes.$.r":"0", "nodes.$.c":"0", "nodes.$.a":"5"}})
You see the $ sign takes the node object it found that matches the first part (query) of the call, and sends you there in the second part (projection) part of your call.
Also check out this question