Is there a way to convert a JMESPath boolean to the opposite value? - boolean

I have a JSON that has a value of true, I want to return false.
Below is an example:
{"a": {"City": "Hello", "flag": false}}
I call a.flag in order to get the false value. However I have not been able to figure out a way to convert the false to true.
I have tried a.flag == false in https://jmespath.org/tutorial.html but it is not working correctly.

Your attempt is not working because your false value is not interpreted correctly in the condition a.flag == false.
What you are really doing when doing a.flag == false is that you are comparing the value of the key false of your JSON object to the value of a.flag.
A way to confirm this is to run the query:
foo.flag == false
Over those two JSON
{
"false": "some value",
"foo": {
"city": "Brussels",
"flag": "some value"
}
}
which will return true
{
"false": "some other value",
"foo": {
"city": "Brussels",
"flag": "some value"
}
}
which will return false
The correct way to compare a value to a boolean in JMESPath is to use a literal expression and, so, put your boolean in backticks `true`.
With the query:
foo.flag == `false`
Over the JSON
{
"foo": {
"city": "Brussels",
"flag": false
}
}
We get the expected: true
And of course, as you commented it, you can simply use a not-expression:
!(foo.flag)

Related

Wiremock: how to validate ALL objects in an array

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

Find query on nested json object

I have document structure like:
{
"date": "2017-02-28T13:06:05Z",
"id": "370adb62d5b1461ead2c4d9410710482",
"json": {
"flag": true,
"key": "abc",
"no":{
"no1":"one",
"no2":"two"
}
}
}
I want to retrive documents where key equals "abc" and no1 equals "one"
Please help !
this should do the trick :
db.collection.find({"json.key": "abc", "json.no.no1": "one"})
try it online: mongoplayground.net/p/XelDmKBa6JS

how to use null parameter in mongodb?

I inputed a parameter, and using mongodb.
My query is
db.collections.find({"tags":parameter});
I want to run query, when parameter is "" (null or "").
It will be
db.collections.find({"tags":""});
It is returned empty value.
How can I use input parameter null or "" in mongoDB?
EDIT
I'm sorry. I'm beginner in here, so sorry.
I want to get all the values returned when I type null
For example, it looks like this my collections,
collections
{
"_id": 0,
"tags": ["happy", "sad", "nice", "bad"]
},
{
"_id": 1,
"tags": ["bad", "gloomy"]
}
I want the same result as below.
> Db.collections.find ({"tags": ""})
{
"_id": 0,
"tags": ["happy", "sad", "nice", "bad"]
},
{
"_id": 1,
"tags": ["bad", "gloomy"]
}
// Return all collections.
> Db.collections.find ({"tags": "happy"})
{
"_id": 0,
"tags": ["happy", "sad", "nice", "bad"]
}
// Return matching collections.
but, db.collections.find ({"tags": ""}) brings out the results of that result is empty.
How can I print out all the results when I enter a null value?
Since a null value can be represented in several ways, depending on the language that wrote to the database in the first place, you need to use a combinations of things. Your query will need to look something like
db.collection.find({$or:[{"tags":{"$type":"null"}}, {"tags": {"$exists":false}}, {"tags":""}]})
Since BSON has a concept of Null, we have type check to see if the field exists but simply has no value. In addition to this, the field could not exist at all, so this must be explicitly checked for. Finally, depending on the language and the way the field was serialized, an empty string is a possibility.
Note that
{"tags":null}
and
{"tags":{"$type":"null"}}
are essentially the same thing.
Here is a quick example
> db.test.insert({"abc":null})
WriteResult({ "nInserted" : 1 })
> db.test.find()
{ "_id" : ObjectId("56670b3072f096ee05a72063"), "abc" : null }
> db.test.find({"abc":{$type:10}})
{ "_id" : ObjectId("56670b3072f096ee05a72063"), "abc" : null }
> db.test.find({"abc":{$type:"null"}})
{ "_id" : ObjectId("56670b3072f096ee05a72063"), "abc" : null }
> db.test.find({"abc":null})
{ "_id" : ObjectId("56670b3072f096ee05a72063"), "abc" : null }
db.test.find({$or:[{"tags":{"$type":"null"}}, {"tags": {"$exists":false}}, {"tags":""}]})
{ "_id" : ObjectId("56670b3072f096ee05a72063"), "abc" : null }
As you can see they all work, although the last query is the most thorough way of testing.
EDIT OP CHANGED QUESTION
You cannot find all values when you type null. That is a value and potential state for a field. You need to do an implicit $and here to get what you want.
db.collection.find({tags:{$exists:true}, tags:{$in:["happy","sad"]}})
How do you actually assemble this in code? Well, that depends on your language, but here is some pseudo code.
def getTags(myTags):
if (tags is None):
db.collection.find({ tags: { "$exists": true } })
else:
db.collection.find({ tags: { "$exists": true }, tags: {"$in": myTags } })
You can also get crafty by using an explicit $and
def getTags(myTags):
query = [{ tags: { "$exists": true } }]
if (tags is Not None):
query.add({tags: {"$in": myTags } })
db.collection.find({ "$and": query })
I hope this answers your question more thoroughly.
The accepted answer isn't suitable for the question(at least nowadays).
In MongoDB >= 3.6.
you can use the $expr operator as follow :
assuming that your parameter name is tagsParam and its value may be an Array or null
db.collections.find({
$or: [
{ $expr: !tagsParam || !tagsParam.length },
{ tags: { $in: paramter } }
]
});
In this case you will get the desired result if the parameter value was ["happy"], null or even an empty array [].

What does it mean in JSON

{
"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.

How to toggle a boolean field in one document with atomic operation?

Is there any way to toggle the boolean field of ONE document in MongoDB with atomic operation? Say, (In python)
cl.update({"_id": ...}, {"$toggle": {"field": 1}})
Right now, I don't think it's possible to do this with one operation. The bitwise operators (http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit) don't have a '$xor' yet although I've a patch for it.
Right now the workaround I think think of is by always using '$inc':
cl.update( { "_id": ...}, { '$inc' : { 'field' : 1 } } );
Then instead of checking for true or false, you can do check whether an item is "true":
cl.find( { "_id": ..., 'field' : { '$mod' : [ 2, 1 ] } );
IE, you using the modulo operator to see whether it's even or uneven with even being "unset", and uneven being "set". If you want to have the oppposite behaviour (ie, find all items that don't have the flag set), then use [ 2, 0 ];
The SERVER-4362 issue is actually resolved now and you have the $bit update operator available. So along with it's xor argument you can now do this in an atomic action:
cl.findOneAndUpdate(
{ "_id": ...},
{
"$bit": {
"field": { "xor": NumberInt(1) }
}
},
{ "returnNewDocument": true, "upsert": true }
);
So as long as the value of field is kept at 0 or 1 then a bitwise "flip" will result that makes the current value the opposite of what it was at the time of the modification.
The .findOneAndUpdate() is not required, but just a way of demonstrating that the resulting value is different on every modification.
You can use update with aggregation pipeline starting from MongoDB v4.2,
1) Option using $not
Evaluates a boolean and returns the opposite boolean value; i.e. when passed an expression that evaluates to true, $not returns false; when passed an expression that evaluates to false, $not returns true.
cl.update(
{"_id": ...},
[
{ "$set": { "field": { "$not": "$field" } } }
]
)
Playground
Drawbacks of $not evaluates as false the following: null, 0, and undefined values and other values as true!
2) Option using $eq
Will set field to true if it is false, and to false if it is any other value.
cl.update(
{"_id": ...},
[
{ "$set": { "field": { "$eq": [false, "$field"] } } }
]
)
Playground