CHRD
CHRD

Reputation: 1957

MongoDB filter on fields in objects in arrays

I have a collection of documents with the following structure (I am including only two documents here). All documents include field1 and array1. And while the number of objects inside array1differs between documents, field_1 and field_2 always exist in the objects.

{
  "_id": "1",
  "field1": "A",
  "array1": {
    "object1": {
      "field_1": "true",
      "field_2": "test"
    },
    "object2": {
      "field_1": "false",
      "field_2": "test"
    }
  }
}

{
  "_id": "2",
  "field1": "A",
  "array1": {
    "object1": {
      "field_1": "true",
      "field_2": "test"
    },
    "object2": {
      "field_1": "true",
      "field_2": "test"
    },
    "object3": {
      "field_1": "false",
      "field_2": "test"
    }
  }
}

{
  "_id": "3",
  "field1": "B",
  "array1": {
    "object1": {
      "field_1": "true",
      "field_2": "test"
    },
    "object2": {
      "field_1": "false",
      "field_2": "test"
    }
  }
}

I am trying to make a query that, for each document where field1 = "A", returns only field1 and the count of objects in array1 where the boolean field_1 is true. (There are many more fields and arrays in the document apart from those included here, so it is important that I only retrieve the specified field and array and not everything). So in this example, I would end up with the following:

{
  "_id": "1",
  "field1": "A",
  "array1": "1"
}

{
  "_id": "2",
  "field1": "A",
  "array1": "2"
}

I have been testing this query below but don't understand where it goes wrong. I can see however that the count always equals zero, so something is wrong.

db.collection.aggregate([
  { "$match": { "field1": "A" }},
  { "$addFields": {
    "array1": {
      "$size": {
        "$filter": {
          "input": "$array1",
          "cond": { "$eq": ["$$this.v.field_1", "true"] }
        }
      }
    }
  }}
])

Any help is highly appreciated!

Upvotes: 0

Views: 39

Answers (1)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

All you need to update is this { "$eq": ["$$this.v.field_1", "true"] } to { "$eq": ["$$this.field_1", "true"] }, there is not such thing called field v inside array field array1 , Also change to $project instead of $addFields to just include field1, _id & array1 in output. Try this :

db.collection.aggregate([{ $match: { field1: 'A' } }, {
    $project: {
        field1: 1, array1: {
            $size: {
                $filter: {
                    "input": "$array1",
                    "as": 'each',
                    "cond": { "$eq": ["$$each.field_1", "true"] }
                }
            }
        }
    }
}])

Upvotes: 1

Related Questions