2

I am new to mongodb and still learning it so my question can be naive so please bear with it :) I have only one json object in mongodb which looks like this.

json object

{
    "URLStore": [
        {
            "description": "adf description",
            "url": "www.adf.com"
        },
        {
            "description": "pqr description",
            "url": "www.pqr.com"
        },
        {
            "description": "adf description",
            "url": "www.adf.com"
        }
    ]
}

I need to query description for url which matches given input. e.g here www.adf.com . I have a code which queries mongodb

mongodb query

BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("URLStore.url","www.pqr.com");
BasicDBObject fields=new BasicDBObject("URLStore.description", "");
cursor = collection.find(whereQuery,fields);

but the result is something like

{
    "_id": {
        "$oid": "554b4046e4b072dd9deaf277"
    },
    "URLStore": [
        {
            "description": "pqr description"
        },
        {
            "description": "adf description"
        },
        {
            "description": "adf description"
        }
    ]
}

Actually only 1 description should have returned as matching objects with key www.pqr.com is only one. What is wrong with my query? m I missing something here ?

I have already tried question Retrieve only the queried element in an object array in MongoDB collection but using solution mentioned there will return only one object / first match

Community
  • 1
  • 1
nishi
  • 1,155
  • 3
  • 12
  • 20
  • possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – famousgarkin May 07 '15 at 10:54
  • @famousgarkin yeah I tried that but it is returning only first matched element. So if I changed my query to something other and if object has more than one matching items then it will return the first matched object – nishi May 07 '15 at 11:28
  • Agreed, the accepted solution is not very useful. Check out the other ones for a generic solution, like using aggregation framework with `$unwind` or `$redact`. – famousgarkin May 07 '15 at 11:34

1 Answers1

3

Use the following aggregation pipeline, should give you the desired results:

db.collection.aggregate([
    {
        "$match": {
            "URLStore.url": "www.adf.com"
        }
    },
    {
        "$unwind": "$URLStore"
    },
    {
        "$match": {
            "URLStore.url": "www.adf.com"
        }
    },
    {
        "$group": {
            "_id": {
                   "url": "$URLStore.url",
                   "description": "$URLStore.description"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "description": "$_id.description"
        }            
    }
])
chridam
  • 88,008
  • 19
  • 188
  • 202
  • 3
    Looking at the code (I have not executed this) I guess it will return only first occurrence of url "www.adf.com" what if there are more than one occurrences of given url. – Harshawardhan May 07 '15 at 12:37
  • @Harshawardhan You are right, I need to change the group id to include both fields so that it groups by URL and description. – chridam May 07 '15 at 12:50