EDIT - See the end of the question for one way to do it:
I have a mongo object with properties like:
{ something: { name: "asdf", childThing: {} } }
and
{ something: { name: "jklh", childThing: {"type": "blah"} } }
How can I write a query that will find the object somethingElse
based on the fact that count(somethingElse.childThing.keys) > 0
I tried this but it's only for arrays, I guess, because it returns all records:
{ 'childThing': { $exists: true, $not: {$size: 0} } }
EDIT: I figured out one way to do this:
{ 'something.childThing': { $not: {$eq: {} } } }
This just matches all documents that have a non-empty value for that child
You can use the $objectToArray
operator to transform the childThing
object to an array:
Converts a document to an array. The return array contains a element
for each field/value pair in the original document.
This way you can get its size (which is the number of fields) and match it to being not 0:
db.collection.aggregate([
{ $addFields: {
"childKeyCount": { "$size": { "$objectToArray": "$something.childThing" } }
}},
{ $match: { "childKeyCount": { "$ne": 0 } } }
// { $project: { "childKeyCount": false } }
])
Given this input:
[
{ "something" : { "name" : "asdf", "childThing" : { } } }
{ "something" : { "name" : "jklh", "childThing" : { "type" : "blah" } } }
]
it gives:
[
{
"something" : { "name" : "jklh", "childThing" : { "type" : "blah" } },
"childKeyCount" : 1
}
]
Use the $expr
operator in your find()
query as it allows the use of aggregation expressions within the query language. You would need an expression that transforms the object with the unknown keys to an array using $objectToArray
and calculate the size of the array with $size
to check the numbers of keys in the object. Once you get the size then run a comparison check with $gt
to be used as the condition for $expr
:
db.getCollection('collectionName').find({
"$expr": {
"$gt": [ { "$size": { "$objectToArray": "$something.childThing" } }, 0]
}
})