MongoDB / Мангуст - агрегация с geoNear и поддокументами
Я использую узел-geoip модуль и выполнение запроса агрегации. Схема, против которой я выполняю запрос, выглядит следующим образом:
var mongoose = require('mongoose');
require('./location.js');
module.exports = mongoose.model('Region',{
attr1: Number,
attr2: String,
attr3: String,
locations:[mongoose.model('Location').schema]
});
и
var mongoose = require('mongoose');
module.exports = mongoose.model('Location',{
attr1: Number,
latlong: { type: [Number], index: '2d' },
});
мне нужно выполнить операцию $geoNear в запросе агрегации, но у меня возникает несколько проблем. Во-первых, вот мой метод агрегации:
var region = require('../models/region');
var geo = geoip.lookup(req.ip);
region.aggregate([
{$unwind: "$locations"},
{$project: {
attr1 : 1,
attr2 : 1,
locations : 1,
lower : {"$cond" : [{$lt: [ '$locations.attr1', '$attr1']}, 1, 0]}
}},
{
$geoNear: {
near: { type:"Point", '$locations.latlong': geo.ll },
maxDistance: 40000,
distanceField: "dist.calculated"
}
},
{ $sort: { 'locations.attr1': -1 } },
{$match : {lower : 1}},
{ $limit: 1 }
], function(err,f){...});
первая проблема, которую я получаю, заключается в том, что, по-видимому, geoNear должен быть на первой стадии трубопровода: exception: $geoNear is only allowed as the first pipeline stage
. Итак, мой вопрос, я могу выполнить geoNear поиск в документах, без их размотки? Если да, то как?
другое сообщение об ошибке я получаю это errmsg: "exception: 'near' field must be point"
. Что это означает и что это означает для моего кода? Я пробовал использовать near
as:
near: { type:"Point", '$locations.latlong': geo.ll },
1 ответов
первый отказ от ответственности: я не эксперт узла/Мангуста, поэтому я надеюсь, что вы можете перевести общие форматы в узел/Мангуст.
ошибки:
errmsg: "exception: 'near' field must be point"
для индекса " 2d " это не может быть GeoJSON, который точка и вместо этого должна быть "устаревшей координатной парой". например,
{
"$geoNear": {
"near": geo.ll,
"maxDistance": 40000,
"distanceField": "dist.calculated"
}
}
Если вы хотите использовать GeoJSON, вам нужно будет использовать индекс "2dsphere".
С этим изменением запрос $geoNear будет работать с массивом точек в запросе. Пример в оболочке:
> db.test.createIndex({ "locations": "2d" })
> db.test.insert({ "locations": [ [1, 2], [10, 20] ] });
> db.test.insert({ "locations": [ [100, 100], [180, 180] ] });
> db.test.aggregate([{
"$geoNear": {
"near": [10, 10],
"maxDistance": 40000,
"distanceField": "dist.calculated",
num: 1
}
}]);
{
"result": [{
"_id": ObjectId("552aaf7478dd9c25a3472a2a"),
"locations": [
[
1,
2
],
[
10,
20
]
],
"dist": {
"calculated": 10
}
}],
"ok": 1
}
обратите внимание, что вы получаете только одно расстояние на документ (ближайшая точка), которое семантически не совпадает с выполнением размотки, а затем определения расстояния до каждой точки. Я не могу быть уверен, если это важно для вашего случая.