0

Suppose I have this MongoDB document:

{
  "_id": {
    "$oid": "628f739398580cae9c21b44f"
  },
  "place":"Amsterdam",
  "events": [
    {
      "eventName": "Event one",
      "eventText": "Event",
      "eventDate": "010101"
      "host":"Bob"
    },
    {
      "eventName": "E2",
      "eventText": "e2",
      "eventDate": "020202"
      "host":"John"
    }
  ]
}

{
  "_id": {
    "$oid": "628f739398580cae9c21b44f"
  },
  "place":"London",
  "events": [
    {
      "eventName": "e3",
      "eventText": "e3",
      "eventDate": "010101",
      "host":"Bob"
    }
  ]
}

And I want to get the array block of events being hosted by Bob, how would I do that? I have tried to use $elemSelector like this:

const result = await mongoDatabase
      .collection("temp")
      .find({ events: { $elemMatch: { eventName: "E2" } } })
      .toArray();

    console.log(JSON.stringify({ result }));

But it just returns all events at the same place as the selected, Amsterdam in this case.

Wanted result:

{
  "eventName": "Event one",
  "eventText": "Event",
  "eventDate": "010101"
  "host":"Bob"
},
{
  "eventName": "e3",
  "eventText": "e3",
  "eventDate": "010101",
  "host":"Bob"
}
1
  • Ended up redoing the document, but thanks for answers and help Commented May 30, 2022 at 22:50

4 Answers 4

1

You can achieve with simple pipeline stages

db.collection.aggregate([
  {
    "$match": {//Match
      "events.host": "Bob"
    }
  },
  {
    "$project": {
      "e": {
        "$filter": {//Filter matching elements
          "input": "$events",
          "as": "event",
          "cond": {
            "$eq": [
              "$$event.host",
              "Bob"
            ]
          }
        }
      }
    }
  }
])

Playground

Sign up to request clarification or add additional context in comments.

Comments

1

Check this out

db.collection.aggregate({
  $unwind: "$events"
},
{
  $match: {
    "events.host": "Bob"
  }
},
{
  "$project": {
    "events": 1,
    "_id": 0
  }
},
{
  "$replaceRoot": {
    "newRoot": "$events"
  }
})

And you can play around with more test data here: https://mongoplayground.net/p/A1UbZdZgZmr

4 Comments

Returns an error message saying aggregate accepts at most two arguments
I found a mongoose bug related to this, so it might be from mongoose if you are using mongoose github.com/Automattic/mongoose/issues/10722
I'm using standard mongoDB, is it not supposed to be capped at two?
I don't think such limitation is from the DB itself, you can find here examples with more than 2: mongodb.com/docs/manual/reference/command/aggregate/#example maybe the driver itself, its version, or the DB version
0

Try with this.

db.getCollection('events_or_whatever_u_').find({'_id': ObjectId('xxxxx')})

1 Comment

This would just get whole documents? Not a specific object in any of the arrays
0

Following Structure can be achieved by using projection query in MongoDB one lucid solution for the above can be this

 db.collection("temp").find({ "events":{ $elemMatch:{ "eventName":"e3" }  } }, {"events":1,"_id":0})

1 Comment

This returns the same as my failed example

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.