Oleh
Oleh

Reputation: 447

Retrieve and update sub document in mongodb

I would like to get from document only its sub document. I have structure like this:

{"_id" : "5ad6729179b9c00808ea9cdf",
"CreatedDate" : ISODate("2018-04-17T22:17:53.696Z"),
"UpdatedDate" : ISODate("2018-04-17T22:17:53.698Z"),
"Label" : "2018-Q1",  
"Sections" : [ 
    {
        "_id" : "5ad6729179b9c00808ea9ce0",
        "Label" : "TWN-25",
        "Groups" : [ 
            {
                "_id" : "5ad6729179b9c00808ea9ce1",
                "Label" : "Group1"                    
            }, 
            {
                "_id" : "5ad6729179b9c00808ea9ce2",
                "Label" : "Group 2"                    
            }, 
            {
                "_id" : "5ad6729179b9c00808ea9ce3",
                "Label" : "Group3"             
            }
        ]
    }, 
    {
        "_id" : "5ad6729179b9c00808ea9ce4",
        "Label" : "TWN-26",
        "Groups" : [ 
            {
                "_id" : "5ad6729179b9c00808ea9ce5",
                "Label" : "Group4"    
            }
        ]
    }
]}

I have next find query

        var builder = Builders<BsonDocument>.Filter;
        var filter = builder.Eq("_id", questionnaireId) & builder.Eq($"Sections._id", sectionId) &
            builder.Eq("Sections.Groups._id", groupId);

But I would like to get only Group sub document from document. For this I have to build Projection. Here is my projection:

var project = Builders<BsonDocument>.Projection.Include("Sections.Groups.$");

And I am calling it like this

var result = Collection.Find(filter).Project(project).FirstOrDefault();

But I am still getting all document, not just sub document Group. What I am doing wrong ?

Upvotes: 0

Views: 143

Answers (1)

Sergii Apostol
Sergii Apostol

Reputation: 311

In ideal world i would suggest you to use following query:

db.getCollection('Test').find(
{
        "Sections.Groups._id":"5ad6729179b9c00808ea9ce3"
}, 
{ 
        "Sections.Groups": 
        {
                "$elemMatch" : {"_id":"5ad6729179b9c00808ea9ce3" } 
        }
} )

But, unfortunately, you will get following exception:

Cannot use $elemMatch projection on a nested field

You basically have two options:

Use aggregation framework

db.Test.aggregate( [
   {$match: { "Sections.Groups._id":"5ad6729179b9c00808ea9ce3" } },   
   {$unwind: "$Sections"},
   {$replaceRoot: { newRoot: "$Sections"} },
   {$unwind: "$Groups"},
   {$replaceRoot: { newRoot: "$Groups"} },
   {$match: { "_id":"5ad6729179b9c00808ea9ce3" }}
] )

Use following query

db.getCollection('Test').find(
{"Sections.Groups._id":"5ad6729179b9c00808ea9ce3"}, 
{"Sections": {"$elemMatch" : {"Groups._id":"5ad6729179b9c00808ea9ce3" } }} )

I would go with first options, although it is not very efficient

Upvotes: 1

Related Questions