2

I have a query where I need to find a document by ID, I then need to only return items inside of an array that match certain conditions.

In the code below you will see that I need to only "match" one document by ID, I am then putting a "limit" of one (there should only be one). This is were I really get confused...I am then "unwind"ing the fragments field which is the array, inside the array are subdocuments. I need to filter out these subdocuments by the last item of an array inside of it, so I "project" a "slice" of the assignments_array. This is were i only need the documents where the assignments_array is EMPTY, or where assignment_history.to is null

db.getCollection('territories').aggregate([
    {
      "$match": {
        "congregation": ObjectId("5c68c706f1f52047f08862b3")
      }
    },
    {
      "$limit": 1
    },

    { 
      $unwind: {
        path: "$fragments"
      }
    },
    {
      $project: {
        "fragments.number": 1,
        "fragments.assignment_history": {"$slice": ["$fragments.assignment_history", -1]}
      }
    }

This gets me this result...

{
  "_id": ObjectId("5c68c706f1f52047f08862b6"),
  "fragments": {
    "number": 1,
    "assignment_history": [{
      "to": ObjectId("5c68c706f1f52047f08862b4"),
      "on": 1550370567067
    }]
  }
}
{
  "_id": ObjectId("5c68c706f1f52047f08862b6"),
  "fragments": {
    "number": 2,
    "assignment_history": []
  }
}
{
  "_id": ObjectId("5c68c706f1f52047f08862b6"),
  "fragments": {
    "number": 3,
    "assignment_history": [{
      "to": null,
      "on": 1550370567067
    }]
  }
}

I need to end up with 2 objects, where assignment_history.to is null, and where assignment_history has no items/length.

1
  • can you show an example object of this territories? Commented Feb 17, 2019 at 16:35

2 Answers 2

2

You can use one more $match condition after the $unwind

db.getCollection('territories').aggregate([
  { "$match": { "congregation": ObjectId("5c68c706f1f52047f08862b3") }},
  { "$limit": 1 },
  { "$unwind": { "path": "$fragments" }},
  { "$match": {
    "$or": [
      { "fragments.assignment_history.to": null },
      { "fragments.assignment_history.to": { "$exists": false }}
    ]
  }},
  { "$project": {
    "fragments.number": 1,
    "fragments.assignment_history": { "$slice": ["$fragments.assignment_history", -1] }
  }}
])
Sign up to request clarification or add additional context in comments.

Comments

0

Try adding this stage before the project. Its mean give me those with empty fragments.assignment_history, or those that have no fragments.assignment_history.to

{
  $match: {
     $or : [
            { "fragments.assignment_history" : {$size: 0}},
            { 
              "fragments.assignment_history" :{
                        $not: { $elemMatch: { to : {$exists: true} } 
              }
            }
           ]
  }
}

Comments

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.