I am currently using MongoDB with node.js and Mongoose to perform geospatial searches.
I'm working with the following documents and collections:
1...n
waypoints1
waypoint Simple example of what these documents may look like:
// Target
{
waypoints: [
{
loc: [61.24, 22.24],
time: 0
},
{
loc: [61.25, 22.24],
time: 1
},
{
loc: [61.26, 22.24],
time: 2
},
]
}
// Source
{
waypoint: {
loc: [61.24, 22.24],
time: 0
}
}
So my question is this:
Given that we have a specific target
document (like the one above), what is the easiest way to find all source
documents near (within distance of MAX_DISTANCE) any of the given waypoints in the target
?
Matching for single waypoint is trivial:
Source.find({
'from.loc': {
$within: {
$center: [target.waypoints[0].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
})
However I'm struggling to find the solution of how to match any of the given waypoints. For instance the following query doesn't work:
Source.find({
$or: [
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[0].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
},
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[1].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
},
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[2].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
}
]
})
Any ideas why this doesn't work and what would be the alternative?
All help is much appreciated!
P.S. I'm using MongoDB v2.0.5, Mongoose 2.7.4 & node v0.8.7
$or
queries are implemented as separate queries internally anyway, so aside from a lack of elegance, something like the following works w/o too much bloat (with a little help from the underscore library):
var nearSources = {}, count = target.waypoints.length;
target.waypoints.forEach(function (waypoint) {
Source.find({
'waypoint.loc': {
$within: {
$center: [waypoint.loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
}, function (err, sources) {
if (sources) {
// Add the unique sources to the nearSources object by _id.
sources.forEach(function (source) {
nearSources[source._id] = source;
});
}
if (--count === 0) {
// Done! Convert nearSources to an array of source docs.
nearSources = _.values(nearSources);
}
});
});