Kit
Kit

Reputation: 21709

How to find documents that contains a field that contains any sub-fields

I have documents that have an attributes field. Something like this:

{
    "_id" : "somestring",
    ...,
    "attributes" : {
        "SomeKey" : {
            "code" : "SomeCode",
            "name" : "SomeName",
        }
    }
}

How do I find all documents that have an attributes field that have 1 or more sub-fields?

The above document would match but the below document would not.

{
    "_id" : "somestring",
    ...,
    "attributes" : {}
}

I know how to query for arrays that have a number of items, and query for documents that have a field that has some specific sub-field, but I'm looking for a document that has a field that has any sub-fields.

Upvotes: 1

Views: 113

Answers (2)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

Instead of using $where to run .js code thru query, you can use try as below :

db.collection.aggregate([
  {
    $match: {
      attributes: {
        $ne: {}
      }
    }
  }
])

/** Or with `.find()` */

db.collection.find({ attributes: { $ne: {} } });

Test : MongoDB-Playground

Just in case if you don't have attributes at all or it exists but not an object then :

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          { $eq: [ { $type: "$attributes" } , "object" ] },
          { $ne: ["$attributes" , {} ] }
        ]
      }
    }
  }
])

/** Or with `.find()` */
db.collection.find({
  $expr: {
    $and: [
      { $eq: [{ $type: "$attributes" }, "object"] },
      { $ne: ["$attributes", {}] },
    ],
  },
});

Test : MongoDB-Playground

Upvotes: 1

Kit
Kit

Reputation: 21709

I found a mechanism that uses $where, but this can run slow because it's Javascript. None of the other built-in operators seem to fit.

db.getCollection('COL')
  .find({
      $where: function() {
        for (field in this["attributes"])
          return true;
        return false;
      }
  })

Upvotes: 0

Related Questions