spirytus
spirytus

Reputation: 10946

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

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 } } } )

Upvotes: 6

Views: 3196

Answers (3)

Sudhanshu
Sudhanshu

Reputation: 457

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);
})

Upvotes: 4

wdberkeley
wdberkeley

Reputation: 11671

Try something like this:

> db.test.drop()
> db.test.insert({ "x" : ["an array"] })
> db.test.insert({ "x" : { "type" : "object" } })
> db.test.find({ "x" : { "$type" : 3 } })
{ "x" : { "type" : "object" } }

Upvotes: -1

Neo-coder
Neo-coder

Reputation: 7840

Try this may be it also help you

db.users.aggregate([{
  "$match": {
      "$nor": [{
          "gyms": {
              "$exists": false
          }
      }, {
          "gyms": {
              "$size": 0
          }
      }, {
          "gyms": {
              "$size": 1
          }
      }]
  }
 }, {
  "$unwind": "$gyms"
}]).pretty()

Upvotes: 0

Related Questions