0

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!

3
  • Is type of array1 field is an array ? Commented Jan 13, 2020 at 21:12
  • Yes. Type of array1 field is array, and object fields are objects. Commented Jan 13, 2020 at 21:13
  • You should've given actual document, as in the given state of this question array1 doesn't seem like an array rather it seems to an object also this object1 thing is also confusing.. Commented Jan 13, 2020 at 21:23

1 Answer 1

1

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"] }
                }
            }
        }
    }
}])
Sign up to request clarification or add additional context in comments.

6 Comments

This gives me an output that looks correct at first, but there are only zeroes in the output for the field "array1". So something must be missing.
@CHRD : Can you give me actual document rather than the JSON that was manually formed .. Does that document look like this { "_id" : "1", "field1" : "A", "array1" : [ { "field_1" : "true", "field_2" : "test" }, { "field_1" : "false", "field_2" : "test" } ] } ??
The actual document is very messy so I am trying to keep it tidy..
It seems to work when I drop the quotations around "true"
Thank you. I do have a boolean as stated in the question. So dropping the quotation works out.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.