Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In MongoDB how to find documents where property is object but not Array

Tags:

mongodb

I have collection users where each contains property gyms e.g.:

{
    "_id" : ObjectId("aaaaa"),
    "firstName" : "first",
    "lastName" : "second",
    "email" : "aaa@aaaa",
    "password" : "aaaaa",
    "gyms" : [
        {
            "name" : "aaaaaa",
            "address" : "aaaaaaaaaaaaa"
        }
    ]
}

However when I run db.users.aggregate(..) I get:

exception: Value at end of $unwind field path '$gyms' must be an Array, but is a Object

It seems that some of the users documents contain gym:{} or no gym at all rather than array. I need to find these documents, how would I do that?

EDIT:

Aggregate command I run:

db.users.aggregate({ $unwind: "$gyms" }, { $match: { "gyms.address": { $exists: true } } } )
like image 281
spirytus Avatar asked Apr 20 '15 12:04

spirytus


People also ask

How do I filter an array of objects in MongoDB?

Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.

How do you find documents with a matching item in an embedded array?

Use $match With $eq to Find Matching Documents in an Array in MongoDB. Use $match With $all to Find Matching Documents in an Array in MongoDB.

How does MongoDB compare array of objects?

You can use $setDifference to compare min with max array and return if there are elements in the min array which are not in max array. Use $expr with $setDifference . $expr allows use of aggregation expressions in the regular find query. You can also look at here to return when there is matching elements in arrays.


1 Answers

Using {$type: "object"} gives you results containing documents with arrays too. So, to check for pure objects, just add an extra check to ensure that arrays are discarded, viz., obj.0.key: {$exists: false}.

In your case,

db.users.find({"gyms": {$type: "object"}, "gyms.0.name": {$exists: false}}).map(function(u) {
    // modify u.gyms to your satisfaction
    db.conversations.save(c);
})
like image 65
Sudhanshu Avatar answered Sep 26 '22 06:09

Sudhanshu