find non-empty fields

4,692 views
Skip to first unread message

Frederico Silva

unread,
Dec 21, 2011, 8:21:22 AM12/21/11
to mongodb-user
Hello,

Is there a way to find only non empty fields on a query?

for instance, I have this collection:

{ title: 't1', authors : { '123' : { name: 'John' }, '456' :
{ name: 'John' } } }
{ title: 't2 }
{ title: 't3', authors : { } }
{ title: 't4' }
{ title: 't5', authors : { '123' : { name: 'John' }, '456' :
{ name: 'John' } } }

collection.find({ authors : { '$exists': true } } )
this will give all the objects with authors set. What if I just want
t1 and t5?

collection.find({ $where : "this.authors &&
Object.keys(this.authors).length > 0" }
something like this will do the job but I'm getting this error
error: {
"$err" : "error on invocation of $where function:\nJS Error:
TypeError: Object.keys is not a function nofile_a:0",
"code" : 10071
}

Can someone give me a hint on this?

Thank you,

Frederico Silva

Sam Millman

unread,
Dec 21, 2011, 9:39:18 AM12/21/11
to mongod...@googlegroups.com
collection.find({ $where : "this.authors &&
this.authors.length > 0" } 

Dunno what you mean by Object.keys() function but the closest I could find was Mozillas own engine:  https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys 

Which means this function only works when running JS inside of Mozilla.


Frederico Silva

--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.


Sam Millman

unread,
Dec 21, 2011, 9:40:36 AM12/21/11
to mongod...@googlegroups.com
Though as I have noticed most other browsers have that function for a while now. But still it is not standard JS as such you cannot rely on it.

Ross Lawley

unread,
Dec 21, 2011, 9:54:37 AM12/21/11
to mongod...@googlegroups.com
Hi,

You could add a $ne lookup to the query like so:

db.test.find({ authors : { '$exists': 1, '$ne': {}}})

Ross

evan chua-yap

unread,
Dec 21, 2011, 9:58:07 AM12/21/11
to mongodb-user
if you have a field inside authors that's required, you could do
something like this:

> db.coll.find({"authors.123": {$exists: true}}).forEach(printjson)
{
"_id" : ObjectId("4ef1ebc81f740f970e77a88a"),
"title" : "t1",
"authors" : {
"123" : {
"name" : "John"
},
"456" : {
"name" : "John"
}
}
}
{
"_id" : ObjectId("4ef1ec68f009a53f701b9227"),
"title" : "t5",
"authors" : {
"123" : {
"name" : "John"
},
"456" : {
"name" : "John"
}
}
}

another possibility is that instead of assigning {} to authors, if you
explicitly assign null to it ,
you could then do the following:

db.coll.find({"authors":{$not:{$type:10}}}).forEach(printjson)

$type:10 means NULL

let me knows if this helps

Sam Millman

unread,
Dec 21, 2011, 10:08:39 AM12/21/11
to mongod...@googlegroups.com
You are correct best hint of all would be to just avoid the $where altogether.

Sam Millman

unread,
Dec 21, 2011, 10:13:12 AM12/21/11
to mongod...@googlegroups.com
db.test.find({ authors : { '$exists': 1, '$ne': {}}}) 

Does not work due to the way mongo uses that array:

> db.test.insert({name: 'woo', address: {}})
> db.test.insert({name: 'woo', address: {street: 25}})
> db.test.find({address: {$ne: {}}})
{ "_id" : ObjectId("4ef1f733e4c8e5b5ef57984b"), "name" : "woo", "address" : { "street" : 25 } }

Sam Millman

unread,
Dec 21, 2011, 10:14:36 AM12/21/11
to mongod...@googlegroups.com
Oh poop, sorry foorget last reply...read wrong

Frederico Silva

unread,
Dec 21, 2011, 10:38:45 AM12/21/11
to mongod...@googlegroups.com
It was just a way to able to easily count the number of properties of a object, instead of a for..in loop. Thanks for your comment. 

Frederico Silva

unread,
Dec 21, 2011, 10:40:42 AM12/21/11
to mongod...@googlegroups.com
That was what I was looking for. Didn't know that the $ne compares objects as well. 

Thank you very much.

Frederico Silva

unread,
Dec 21, 2011, 10:50:47 AM12/21/11
to mongod...@googlegroups.com
In my solution I can't use null assignment to the object because updates/inserts on the author will fail.

coll.update({ 'title' : 't5'}, { $set : { 'authors.123.age' : 18 } })

the forEach approach all big part of the collection will be transmitted to the client, am I right? I'm trying to minimize that overload (I don't before hand author ids .)

Thank you for your comment.

Sam Millman

unread,
Dec 21, 2011, 11:02:13 AM12/21/11
to mongod...@googlegroups.com
Yea. Tbh the second answer was the best one from Ross I think. That allowed for you to keep nesting object even with empty and also allowed you to tell the difference.

--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To view this discussion on the web visit https://groups.google.com/d/msg/mongodb-user/-/33sl5hHT3VQJ.
Reply all
Reply to author
Forward
0 new messages