Mongo {$ne : null} not working as expected - mongodb

When I issue the following query:
db.users.find({"pic.status" : {$ne : null} }, {"pic" : 1}).toArray()
I expect to receive all users whose pic.status is NOT null. However, the actual result looks something like this:
{
"_id" : ObjectId("4f1e1ab9cdf9dbaa160000bf"),
"pic" : {
"id" : "4f1e1ab9cdf9dbaa160000be",
"status" : null
}
},
{
"_id" : ObjectId("4f1e28480eaf38193d00006f"),
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : null
}
}
That is, I receive users whose pic.status IS null. How can I fix this?

I know it's an old question, and might not be relevant anymore, but as there was no accepted answer, I thought I'll comment for anyone looking for answer.
I was able to reproduce the problem on MongoDB version 2.4.9.
> db.sourceListings.findOne({displayed:{$ne:null}});
{
<.. other stuff went here..>
"displayed" : null
}
The problem disappears on Version 2.6.1:
> db.sourceListings.findOne();
{
<.. other stuff ..>
"displayed" : null
}
> db.sourceListings.findOne({displayed:{$ne:null}});
null
Probably was fixed somewhere in between these two versions.

I cannot seem to reproduce this. What version of Mongo are you using? (I am using 2.1.1-pre) Here are the steps that I took. The following is from the JS shell:
> db.users.save({
"_id" : 1,
"pic" : {
"id" : "4f1e1ab9cdf9dbaa160000be",
"status" : null
}
});
> db.users.save({
"_id" : 2,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : null
}
});
> db.users.save({
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
});
> db.users.find({"pic.status":{$ne:null}}, {pic:1}).toArray()
[
{
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
}
]
Only the document containing "pic.status":"Something" is returned.
My only thought is, are you absolutely certain that the value of (null) in the query is the same as what is saved in the documents? Were the documents saved using the JS shell, or were they saved using a driver in a different language? Theoretically, null, should be null, should be null, in any language, but I know that different languages represent "no value" differently. In python, for example, the value for "no value" is (None). (null) is not recognised in python.
In a python shell, I attempted to save a document with (null) as a value, but received an error:
In [13]: coll.save({"_id":5, "pic":{"id":5, "status":null}})
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/Users/mbastien/mongodb-osx-x86_64-2.0.1/bin/<ipython-input-13-1ad232456c88> in <module>()
----> 1 coll.save({"_id":5, "pic":{"id":5, "status":null}})
NameError: name 'null' is not defined
I then inserted (with the Python shell) a status of 'null' ('null' being a string)
In [15]: coll.save({"_id":5, "pic":{"id":5, "status":'null'}})
Out[15]: 5
Not surprisingly, when I reran the query in the JS shell, this document was returned, because 'null' != null
> db.users.find({"pic.status":{$ne:null}}, {pic:1}).toArray()
[
{
"_id" : 3,
"pic" : {
"id" : "4f1e28480eaf38193d00006e",
"status" : "Something"
}
},
{
"_id" : 5,
"pic" : {
"status" : "null",
"id" : 5
}
}
]
Is this similar to what you are experiencing, or can you reproduce this 100% in the JS shell? Hopefully, we will be able to get to the root of this issue!

Use $nin with a single element in the array. It'll behave as you expect. KI with many of the people who use mongo.

Related

How to get all subfields of mongodb in a query when one field is root field of other field requested?

For this specific case, everything works fine, except when
for the fields field1,field2 requested, and field1 is a part of field2.
Example :
> db.mycoll.findOne()
{
"_id" : 1,
"data" : {
"amounts" : {
"dollar" : 20,
"euro" : 18
},
"item" : "toy",
"sale" : false
}
}
// works well
> db.mycoll.findOne({"_id":1},{ "data.amounts.dollar":1 })
{ "_id" : 1, "data" : { "amounts" : { "dollar" : 20 } } }
// here "data" is root of "data.amounts.dollar" and "data.amounts.euro"
// takes preference, how to query for "data", so
// that all subfields of data are
// returned
> db.mycoll.findOne({"_id":1},{ "data":1 , "data.amounts.dollar":1 })
{ "_id" : 1, "data" : { "amounts" : { "dollar" : 20 } } }
Expected output :
{
"_id" : 1,
"data" : {
"amounts" : {
"dollar" : 20,
"euro" : 18
},
"item" : "toy",
"sale" : false
}
}
Yes, it is possible to format the subfields on the program side, and send the root field to mongodb query, but my question is if this is feasible on the querying side without Javascript .
This is unusual behavior, a bug to be precise.
From credible/official sources :
Jira Open Bug
Jira Bug Duplicate
Seems that the bug is still open.
Please let me know if you need any further analysis.
db.mycoll.findOne({"_id":1},{"data.amounts.dollar":1,"data":1 })
This gives as expected result
db.getCollection(coll_name).find({_id:1},{data:1});
This will give output
{
"_id" : 1,
"data" : {
"amounts" : {
"dollar" : 20,
"euro" : 18
},
"item" : "toy",
"sale" : false
}
}
Once you use a projection (the second json document in the 'find()', only those fields specified in the projection will be returned by the server (The exception is '_id' which will be returned unless explicitly turned off by _id:0).
{ "data":1 , "data.amounts.dollar":1 }
By selecting data.amounts.dollar inside the sub-document, you have essentially turned off the other members of the data.amounts document.
You can turn them on like you did with dollar, but I think you want them all projected regardless of knowing or not the field names.
I could not find in the documentation anything about order of fields in the projection field.
From the Mongo Documentation here
https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/#projection-document

mongodb set null in update

I have to interchange the values of a document.
var query = {"_id" : ObjectId("53e1c254382f891cc600076d")};
db.properties.find(query).forEach(function(prop){
printjson({"_id":prop._id, "val":prop.val, "ua":prop.ua});
db.properties.update(query, {$set:{ua: prop.val}},{$unset:{val:""}});
});
Before update operation, document looks like this:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : 9876541,
"ua" : null
}
And after the update it turns to:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : 9876541,
"ua" : 9876541
}
But I expect it as:
{
"_id" : ObjectId("53e1c254382f891cc600076d"),
"val" : null,
"ua" : 9876541
}
But its not working. also setting "val" null ({$set:{val:null}}) directly it deleted my entire document.
Setting undefined, It worked like a charm!!
db.properties.find(query).forEach(function(prop){
db.properties.update(query, {$set:{ua: prop.val, val:undefined}});
});
I know this is old, but your syntax for the update function is wrong. The update object should be one single object: db.properties.update(query, {{$set:{ua: prop.val}},{$unset:{val:""}}});

MongoDB: select * from raw which has "1st connector" as 1 of the column

I want to write this query in MongoDB select * from raw, which has "1st connector" as 1 of the column.
I have written:
db.raw.find({},{"1st Connector":1})
I am getting the following results:
> db.raw.find({},{"1st Connector":1})
{ "_id" : ObjectId("548b4e270f02f305e8220370") }
{ "_id" : ObjectId("548b4e270f02f305e8220371") }
When I write "1st connector" without quotes, I get an error:
> db.raw.find({},{1st Connector:1})
2015-02-27T09:50:20.956-0800 SyntaxError: Unexpected token ILLEGAL
I want to see the actual data, i.e. contents of all these objects. How can I see that?
When I do db.raw.find(), I get all the data.
I wrote a similar query and I got the following result:
> db.raw.find({},{entityType:1})
{ "_id" : ObjectId("548b4e270f02f305e8220370"), "entityType" : "parishes" }
{ "_id" : ObjectId("548b4e270f02f305e8220371"), "entityType" : "parishes" }
{ "_id" : ObjectId("548b4e270f02f305e8220372"), "entityType" : "parishes" }
Also, I don't know why am I getting entityType in result here.
I have written : db.raw.find({},{"1st Connector":1})
Because your probably don't have field named "1st Connector" in your document.
I write 1st connector, I get error
2015-02-27T09:50:20.956-0800 SyntaxError: Unexpected token ILLEGAL
Because 1st Connector should be quoted
wrote a similar query and I got the following result:
db.raw.find({},{entityType:1})
{ "_id" : ObjectId("548b4e270f02f305e8220370"), "entityType" : "parishes" }
{ "_id" : ObjectId("548b4e270f02f305e8220371"), "entityType" : "parishes" }
{ "_id" : ObjectId("548b4e270f02f305e8220372"), "entityType" : "parishes" }
Because your have entityType field in your document and the second argument in find is the projection argument this is pretty clear in the documentation

MongoDB Semantics of undefined vs. null in cursor.sort()

According to information in the MongoDB manpage on cursor.sort (last paragraph on comparing values), NULL values are smaller than any other values in terms of the sort() function.
The question is, are missing attributes regarded as NULL? According to my testing not so:
> db.sort.find().sort({id:1})
{ "_id" : ObjectId("5269554df18e7d2f4bd1241d"), "a" : "Anonym" }
{ "_id" : ObjectId("52695684f18e7d2f4bd12421"), "a" : "Bnonym", "d" : "iii" }
{ "_id" : ObjectId("52695892f18e7d2f4bd12422"), "id" : null, "a" : "Bnonym", "d" : "iii" }
{ "_id" : ObjectId("5269591bf18e7d2f4bd12425"), "id" : null, "a" : "ZZZaaa", "d" : "iii" }
{ "_id" : ObjectId("526954d4f18e7d2f4bd1241b"), "id" : 7, "a" : "Jozo" }
The order seems to be:
undefined/missing sort attribute
null value
the rest according to the order from manpage
Q: The question is, whether there is some undocumented type different from null for missing attributes under the hood?
As far as I can tell (I haven't reviewed the source code specifically), this is undefined and depends on a variety of factors. The most striking one is that reversing the sort does not, in general, reverse the order of null / undefined elements:
> db.sort2.find().sort({"a" : 1});
{ "_id" : ObjectId("526a4d45b4e29833675fb089"), "a" : null }
{ "_id" : ObjectId("526a4d4cb4e29833675fb08b") }
{ "_id" : ObjectId("526a4d48b4e29833675fb08a"), "a" : 21433 }
>
> db.sort2.find().sort({"a" : -1});
{ "_id" : ObjectId("526a4d48b4e29833675fb08a"), "a" : 21433 }
{ "_id" : ObjectId("526a4d45b4e29833675fb089"), "a" : null }
{ "_id" : ObjectId("526a4d4cb4e29833675fb08b") }
Also, when I created an index on a for that test collection, the order changed(!). It didn't change back, however, when I dropped the index. For me, the lack of documentation alone would be enough not to rely on that behavior, but it seems largely unpredictable in even the most simple scenario.
A well-defined and important difference of null and non-existant fields is when using sparse indexes: In a sparse index, null is a valid value and will actually be indexed (it has a value, after all), while a non-existant field is not added to the index at all.

MongoDB queries with null value

My collection (MongoDB v 2.0.2) has following records:
db.organization.find({})
{ "_id" : 1001, "path" : [ ], "parent" : null }
{ "_id" : 1002, "path" : [ 1001 ], "parent" : NumberLong(1001) }
organization has indexes:
db.organization.ensureIndex({"path":1});
db.organization.ensureIndex({"parent":1},{sparse:false});
(note I put awarnes sparse : false - to grant that null is indexed)
But, executing:
db.organization.find({"parent":null})
Returns empty set. What is wrong? Thank you in advance
I had the same issue. After reading the following documents
querying and nulls
BSON specification
I tried to query for the different BSON element types and found that my null was represented as a BSON element type 6 (undefined, deprecated) instead of the expected BSON element type 10 (null).
db.collection.find({ field: { "$type" : 6} };
Just checked following script at 2.0 and 2.0.2:
db.items.insert({ "_id" : 1001, "path" : [ ], "parent" : null })
db.items.insert({ "_id" : 1002, "path" : [ 1001 ], "parent" : NumberLong(1001) })
db.items.ensureIndex({"path":1});
db.items.ensureIndex({"parent":1},{sparse:false});
db.items.find({"parent":null})
actually returns one document that you expect:
{ "_id" : 1001,
"path" : [],
"parent" : null }
Also you can look into this doc about querying and nulls, probably should help you avoid possible future mistakes.