You could approach this in a couple of ways. The first is to use the numeric array indexes in the query object keys using the dot notation and the $exists
operator to search all documents that won't have at least a sub_field
array element:
var cursor = db.collection.find({ "field1.sub_field.0": { "$exists": false } })
which should translate to PHP as
$cursor = $collection->find( array("field1.sub_field.0" => array("$exists" => false))
The other way would be to use the $size
operator together with the $exists
operator all wrapped within a $or
operator to find all documents without a sub_field
either non existent or empty array:
var cursor = db.collection.find({
"$or": [
{ "field1.sub_field": { "$exists": false } },
{ "field1.sub_field": { "$size": 0 } }
]
});
Another approach you could consider though with slower performance, would be to use the $where
operator:
var cursor = db.collection.find({
"$where": "this.field1.sub_field.length == 0"
});
For benchmark testing, try populating a test collection:
db.test.insert([
{ field1: { sub_field: [] } },
{ field1: { sub_field: [ "foo" ] } },
{ field1: { sub_field: [ "foo", "bar" ] } }
]);
> db.test.find({ "field1.sub_field.0": { "$exists": false } })
> db.test.find({
"$or": [
{ "field1.sub_field": { "$exists": false } },
{ "field1.sub_field": { "$size": 0 } }
]
})
> db.test.find({ "$where": "this.field1.sub_field.length == 0" })
All the three queries will yield the document that has an empty sub_field
array:
/* 0 */
{
"_id" : ObjectId("568ccec3653d87e43482c4d0"),
"field1" : {
"sub_field" : []
}
}