0

Please refer the following document

{
    "_id" : ObjectId("594b9eb9e1b22e09f8af00ee"),
    "Name" : "Master List",
    "UserId" : ObjectId("594b9eb9e1b22e09f8af00ed"),
    "Items" : [ 
        {
            "_id" : ObjectId("59485d9d0fd04d1294e06766"),
            "Title" : "Muscle Milk Protein",
        }, 
        {
            "_id" : ObjectId("59485d9d0fd04d1294e06772"),
            "Title" : "Baby Macro Organic 120g",
        }, 
        {
            "_id" : ObjectId("59485d9d0fd04d1294e06780"),
            "Title" : "Fruit Bread Soft Strap",
        }
    ]
}

From the above document, I want results based on the search string For eg: "/.Mus./" I should get the following result, but I am getting entire Items details as above

{
    "_id" : ObjectId("594b9eb9e1b22e09f8af00ee"),
    "Name" : "Master List",
    "UserId" : ObjectId("594b9eb9e1b22e09f8af00ed"),
    "Items" : [ 
        {
            "_id" : ObjectId("59485d9d0fd04d1294e06766"),
            "Title" : "Muscle Milk Protein",
        }
    ]
}

I tried the following queries but none of this fetches the matched title from Items subdocument

Query1: db.getCollection('List').find({'UserId': new ObjectId("594b9eb9e1b22e09f8af00ed"), 'Items': {'$elemMatch': {'Title': <code>{$regex:'.*uscle. *'}}}})

Query2: db.getCollection('List').find({'UserId': new ObjectId("594b9eb9e1b22e09f8af00ed"), 'Items.Title': <code> {$regex:'.*Mus. *'}})

Can you please help?

Thanks in advance.

s7vr
  • 63,888
  • 5
  • 68
  • 99

1 Answers1

0

Use the aggregation framework to $unwind, "unpack", the nested array.

db.getCollection.aggregate([
    {
      $unwind:"$Items"
    },
    {
      $match: {
        "Items.title": {
          regex: /yourPattern/
        }
      }
    }
])

Hope it helps! Aggregation is truly awesome in MongoDB.

dasdachs
  • 607
  • 9
  • 15
  • Is there any chance to accommodate same logic in find()? – user2032292 Jun 23 '17 at 04:30
  • I am afraid not. Is there a reason you want to use find? – dasdachs Jun 23 '17 at 05:33
  • No specific reason. Just wanted to know if this can be achieved using find(), if yes can you please help? I tried following query pattern for my requirement, seems working fine. db.getCollection('List').aggregate({ $unwind:"$Items" }, { $match: { "Items.Title": { $regex: '.*Mus.*' }}}, { $match: { "UserId": new ObjectId( "594b9eb9e1b22e09f8af00ed" ) }}) – user2032292 Jun 23 '17 at 13:22
  • Glad to see that `$unwind` is working for you. I have no idea how you could get the same result with `find()`, maybe with `forEach()`, but I am just geussing. As for your query, you can use `$and` with `$match`: `db.getCollection('List').aggregate([{ $unwind: "$Items" }, { $match: {$and: [{ "Items.Title": { $regex: '.*Mus.*' }}, { "UserId": new ObjectId( "594b9eb9e1b22e09f8af00ed" )}]}}])` (I hope I got all the parantheses). – dasdachs Jun 23 '17 at 14:03