5

I have collection of restaurant record .Some of restaurant in this collection belongs to some group(chain type restaurant eg. KfC etc) while other doesn't has any group(Individual restaurant ,that doesn't belongs to any chain).

example :

Restaurant collections

{_id:"1",title:"rest1",address:"somethingx",chain_id:"123"},
{_id:"2",title:"rest2",address:"somethingx",chain_id:"123"},
{_id:"3",title:"rest3",address:"somethingy",chain_id:"0"},
{_id:"4",title:"rest4",address:"somethingx",chain_id:"0"} 

Chain collection :

{_id:"123",chain_name:"VSWEETS",address_deatils:[
                                          {restID:"",address:"somethingx"},
                                          {restID:"",address:"somethingx"}
                                         ]
}

{_id:"456",chain_name:"KFC",address_deatils:[]}

I need to fetch distinct restaurant with similiar chain_id, i.e, only single restaurant should come if it belongs to some chain(chain_id !=0)

Community
  • 1
  • 1
Vishal Sharma
  • 178
  • 10
  • can you post your output? – Neo-coder Jun 04 '15 at 10:35
  • like if i search for restaurant for address "somethingx" . i need to get following results {_id:"1",title:"rest1",address:"somethingx",chain_id:"123"}, {_id:"4",title:"rest4",address:"somethingx",chain_id:"0"} – Vishal Sharma Jun 04 '15 at 10:52
  • still unclear if you pass `address:somethingx` then which collection to used to find `Restaurant` or `Chain` and which relation to used, you mentioned in `chain_id !=0` and output contains `{_id:"4",title:"rest4",address:"somethingx",chain_id:"0"} ` – Neo-coder Jun 04 '15 at 11:08
  • Sorry for confusion @yogesh. I need to query on restuarant collection. – Vishal Sharma Jun 04 '15 at 11:23

1 Answers1

3

You could use the aggregation framework for this. The aggregation pipeline would have the first step as $match operator that filters the restaurants on the address. The $group pipeline stage will then group the filtered documents by the chain_id key and applies the accumulator expression $first to the $$ROOT system variable on each group. You can the reshape the documents using the $project pipeline stage.

The final aggregation pipeline that gives you the desired results follows:

db.restaurant.aggregate([
    {
        "$match": { "address" : "somethingx" }
    },
    {
        "$group": {
            "_id": "$chain_id",
            "data": { "$first": "$$ROOT" }
        }
    },
    {
        "$project": {
            "_id" : "$data._id",
            "title" : "$data.title",
            "address" : "$data.address",
            "chain_id" : "$data.chain_id"
        }
    }
])

Output:

/* 0 */
{
    "result" : [ 
        {
            "_id" : "4",
            "title" : "rest4",
            "address" : "somethingx",
            "chain_id" : "0"
        }, 
        {
            "_id" : "1",
            "title" : "rest1",
            "address" : "somethingx",
            "chain_id" : "123"
        }
    ],
    "ok" : 1
}
chridam
  • 100,957
  • 23
  • 236
  • 235
  • Thanks, I really appreciate your help . this answer took close to what i actually needed. can you help me with pagination & sort – Vishal Sharma Jun 05 '15 at 09:03
  • @VishalSharma No worries, glad to be of help. As for pagination and sorting, consider applying the following pipeline operators: **`$limit`** to limit the number of documents in the result, [**`$skip`**](http://docs.mongodb.org/manual/reference/operator/aggregation/skip/#pipe._S_skip) to skip the first `n` documents where `n` is the specified skip number and passes the remaining documents unmodified to the pipeline, and finally [**`$skip`**](http://docs.mongodb.org/manual/reference/operator/aggregation/sort/#pipe._S_sort) to reorder the document in the result by a specified sort key. – chridam Jun 05 '15 at 09:11