AlokRagate
AlokRagate

Reputation: 1

MongoDB - Return matched sub-document from an array based on condition

Imagine a document like below -

I want to return the PART along with Input's would be language say "ENG" or "FRA" or "GER"

Document-

{
    "_id" : ObjectId("56a5337f19d312a4156a3625"),
    "PartId" : "Part1",
    "Name" : "Name",
    "active" : "true",
    "attribute1" : "value1",
    "attribute2" : "value2",
    "LanguageData":[ 
        {
            "Language" : "ENG",
            "description" : "PARt1- English",
            "default" : "true"
        }, 
        {
            "Language" : "FRA",
            "description" : "Part1 in french",
            "supported" : "true"
        }, 
        {
            "Language" : "GER",
            "description" : "Part1 In German",
            "supported" : "false"
        }
    ]
}

If input is "ENG"

{
    "_id" : ObjectId("56a5337f19d312a4156a3625"),
    "PartId" : "Part1",
    "Name" : "Name",
    "active" : "true",
    "attribute1" : "value1",
    "attribute2" : "value2",
    "LanguageData":[ 
        {
            "Language" : "ENG",
            "description" : "PARt1- English",
            "default" : "true"
        }
    ]
}

If input is "GER" the out put should not return this document as "supported is false"

{}

If input is say "CHN" then default should be returned -

{
    "_id" : ObjectId("56a5337f19d312a4156a3625"),
    "PartId" : "Part1",
    "Name" : "Name",
    "active" : "true",
    "attribute1" : "value1",
    "attribute2" : "value2",
    "LanguageData":[ 
        {
            "Language" : "ENG",
            "description" : "PARt1- English",
            "default" : "true"
        }
    ]
}

I am not able to return sub document based on the conditions

Only the subdocument from array should be returned based on below conditions

1) So if language is present, then return that sub document.

2) If Sub-Document is not present always return default.

3) If Sub Document is present and not supported , do not return the whole document

Upvotes: 0

Views: 592

Answers (1)

zangw
zangw

Reputation: 48356

To query the subdocument, you can do that through aggregate

db.document.aggregate([
    {$match: {'LanguageData.Language': 'GER'}},
    {$project: {
        LanguageData: {$filter: {
            input: '$LanguageData',
            as: 'LanguageData',
            cond: {$eq: ['$$LanguageData.Language', 'GER']}
        }}
    }}
])

For return the default data, the $ifNull could do that

db.document.aggregate([
    {$unwind: '$LanguageData'}, 
    {$match: {'LanguageData.Language': 'GER'}}, 
    {$project: 
       {LanguageData: 
          {Language: {$ifNull: ['$LanguageData.Language', 'CHN']}, 
           description: {$ifNull: ['$LanguageData.description', 'default description']}}}}
]);

Upvotes: 2

Related Questions