Search code examples
arraysjsonmongodbfilterattributes

Query in getting value of second attribute after giving value of first attribute inside array in Mongo db


I am a newbie in Mongo .

I have a requirement to build a query from a complex document inside a collection.

{ "_id" : "http://nsgfds.com",
        "has Title" : [
                {
                        "title" : {
                                "language" : "eng",
                                "value" : "eng title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "chi",
                                "value" : "Chinese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "vie",
                                "value" : "Vietnamese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "asm",
                                "value" : "Assamese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                }
        ]
}

My query wants to return value of "value" field when "language" and "_id" values given

suppose when I give "_id" and "language" the query should return only value of the "value" field based on "_id" and "language". My query:

db.collectionname.aggregate([
  {$match: {"_id": "http://nsgfds.com"}},
  {  
    $project: {
      hasTitle: {
        $filter: {
          input: "$hasTitle", 
          as:"item", 
          cond: { $eq: ["$title.language:eng", "$$item.value"]}
        }
      }
    }
  }
]).pretty();

Expected output:

{
"_id" : "http://nsgfds.com",
"hasTitle" : [{"title" : {"value" : "Wiley Title English title"}]
};

Actual Output:

{
        "_id" : "http://nsgfds.com",
        "hasTitle" : [
                {
                        "title" : {
                                "language" : "eng",
                                "value" : "Wiley Title English title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "chi",
                                "value" : "chinese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "vie",
                                "value" : "Vietnamese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                },
                {
                        "title" : {
                                "language" : "asm",
                                "value" : "Assamese title"
                        },
                        "origin" : "https://Ignore",
                        "score" : 7.5
                }
        ]
}

Solution

  • The error comes from your condition, where you should compare an element of the list ($$item) with a string (eng, asm, shi ...)

    {
        $eq: [
            "$$item.title.language",
            "eng"
        ]
    }
    

    But this will give you :

    [
      {
        "_id": "http://nsgfds.com",
        "hasTitle": [
          {
            "origin": "https://Ignore",
            "score": 7.5,
            "title": {
              "language": "eng",
              "value": "eng title"
            }
          }
        ]
      }
    ]
    

    To get your desired output, you will need another $project

    {
        $project: {
            "hasTitle.title.value": "$hasTitle.title.value"
        }
    }
    

    result :

    [
      {
        "_id": "http://nsgfds.com",
        "hasTitle": [
          {
            "title": {
              "value": [
                "eng title"
              ]
            }
          }
        ]
      }
    ]