vaibhav
vaibhav

Reputation: 4103

Using $geoWithin with the result from another query

Trying to use Geo Spatial queries of Mongo DB my documents are like: Location document:

{
    "_id": ObjectId("57062a9253e564e0d522f001"),
    "geofences": [
        {
            "geofenceId": "geoFence1",
            "loc": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            -11900093200000002,
                            33.53589500000004
                        ],
                        [
                            -118.96275899999999,
                            33.48520500000012
                        ],
                        [
                            -118.98051199999996,
                            33.42859300000009
                        ],
                        [
                            -119.05307099999987,
                            33.411024
                        ],
                        [
                            -119.094128,
                            33.426871999999946
                        ],
                        [
                            -119.10887899999999,
                            33.451151000000095
                        ],
                        [
                            -119.10721499999987,
                            33.50002300000011
                        ],
                        [
                            -119.11894899999999,
                            33.500022
                        ],
                        [
                            -119.10871799999988,
                            33.519264000000135
                        ],
                        [
                            -119.07014300000003,
                            33.536415999999974
                        ],
                        [
                            -119.00093200000002,
                            33.53589500000004
                        ]
                    ]
                ]
            }
        }
    ]
}

Asset Document:

{
    "_id": ObjectId("536b150c30048054e3480789"),
    "loc": {
        "type": "Point",
        "coordinates": [
            -120.954436,
            37.625814000000005
        ]
    },
    "name": "kingize",
    "type": "priceless",
    "code": "pwd"
}

they get inserted properly but when i am trying to do following:

var myloc = db.locations.find().next()
 db.assetlocation.find( { loc : { $geoWithin : { $geometry : myloc.geofences } } })

I am getting:

error: {
    "waitedMS" : NumberLong(0),
    "ok" : 0,
    "errmsg" : "Point must only contain numeric elements",
    "code" : 2
}

I think this error would have come on the insert statements only but to my surprise they worked just perfectly.

Upvotes: 0

Views: 913

Answers (2)

Saleem
Saleem

Reputation: 8978

You are passing wrong parameter to your query. Instead of passing geofences object, pass geofences[0].loc field which contains actual coordinates and geometry type.

Since geofenches is an array, you can loop through to get single geometry.

Try following code snippet, it should fetch document with selected criteria.

var myloc = db.locations.find().next()

var coor = myloc.geofences[0].loc;

db.assets.find( { loc : { $geoWithin : { $geometry : corr } } })

Upvotes: 1

Neil Lunn
Neil Lunn

Reputation: 151112

The problem is that your "geofences" property within the documents contained in the "locations" collection is actually an "array". So the data in that direct form is not suitable for use with $geoWithin.

In order to supply the "loc" data to $geoWithin you need to actually iterate each array element of "geofences" and pass in the data from that each element:

var results = [];
var cursor = db.locations.find();

// Iterate the cursor
while ( cursor.hasNext() ) {
   var doc = cursor.next();

   // Iterate each geofences element
   doc.geofences.forEach(function(fence) {
       // Query to array of results
       var assets = db.assetlocation.find({ 
           "loc": { 
               "$geoWitin": {
                   "$geometry": fence.loc
               }
           }
       }).toArray();
       // Append to the total results
       results = results.concat(assets);
   });
}

// Print all results
printjson(results);

So you need to get at each array element within each result document "first", then you can use the data contained to supply to your query on the "assetlocation" collection and collect of of the results obtained.

Upvotes: 1

Related Questions