Pascal Chatterjee
Pascal Chatterjee

Reputation: 95

Filtering MongoDB geoNear commands with a query

I have a MongoDB collection with the following document in it:

{
    "_id" : ObjectId("4eb479a61258ec97acd1034d"),
    "places" : [
        {
            "coords" : [1,0],
            "remaining" : 1
        },
        {
            "coords" : [0,0],
            "remaining" : 0
        },
}

I have also set a compound, multi-location index on {places.coords: "2d", 'places.remaining':1}

I would like to search for all documents that have a place close to [0,0] and also have remaining > 0, and also the coords of the places that matched.

However, running the command

db.runCommand(
    {
      'geoNear':"mycollection", 
      near:[0,0], 
      query:{'places.remaining': {'$gt': 0}}, 
      includeLocs: true
    }
)

Returns:

{
    "ns" : "test.mycollection",
    "near" : "1100000000000000000000000000000000000000000000000000",
    "results" : [
        {
            "dis" : 0,
            "loc" : {
                "0" : 0,
                "1" : 0
            },
            "obj" : {
                "_id" : ObjectId("4eb479a61258ec97acd1034d"),
                "places" : [
                    {
                        "coords" : [
                            1,
                            0
                        ],
                        "remaining" : 1
                    },
                    {
                        "coords" : [
                            0,
                            0
                        ],
                        "remaining" : 0
                    }
                ]
            }
        },
        {
            "dis" : 1,
            "loc" : {
                "0" : 1,
                "1" : 0
            },
            "obj" : {
                "_id" : ObjectId("4eb479a61258ec97acd1034d"),
                "places" : [
                    {
                        "coords" : [
                            1,
                            0
                        ],
                        "remaining" : 1
                    },
                    {
                        "coords" : [
                            0,
                            0
                        ],
                        "remaining" : 0
                    }
                ]
            }
        }
    ],
    "stats" : {
        "time" : 0,
        "btreelocs" : 0,
        "nscanned" : 2,
        "objectsLoaded" : 1,
        "avgDistance" : 0.5,
        "maxDistance" : 1.0000124312194423
    },
    "ok" : 1
}

i.e. both places, even though the place with coords [0,0] has remaining = 0.

My suspicion was that the query wasn't having any effect but when I run

db.runCommand(
    {
        'geoNear':"mycollection", 
        near:[0,0], 
        includeLocs: true, 
        query:{'foo':'bar'}
    }
)

no places are returned:

{
    "ns" : "test.mycollection",
    "near" : "1100000000000000000000000000000000000000000000000000",
    "results" : [ ],
    "stats" : {
        "time" : 0,
        "btreelocs" : 0,
        "nscanned" : 2,
        "objectsLoaded" : 1,
        "avgDistance" : NaN,
        "maxDistance" : 0
    },
    "ok" : 1
}

Does anyone have any idea what's going wrong? Is what I want even possible with geoNear? Thanks in advance.

Upvotes: 1

Views: 2242

Answers (1)

RameshVel
RameshVel

Reputation: 65857

It is because that you have places inside the other document as embedded. Mongodb doesn't have the ability(as of now) to return only the sub documents even though the positional operator $ exists. $ operator currently works with update the particular sub documents.

This is the behavior of filtering multi level embedded document, normally the matching filter would return the whole document, not the subsets.

So you need to change your doc structure.Instead storing multiple places inside the doc, split them into separate doc. It will give the ability you wanted.

For more info refer How to make a query in this nested document structure (MongoDB)?

Upvotes: 1

Related Questions