javascript - MongoDB/Mongoose - 与 geoNear 和子文档的聚合

标签 javascript mongodb mongoose geolocation aggregation-framework

我正在使用 node-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 显然必须在管​​道的第一阶段:异常:$geoNear 只允许作为第一管道阶段。所以我的问题是,我可以在子文档中执行 geoNear 搜索而不展开它们吗?如果有,怎么做?

我收到的另一条错误消息是 errmsg:\"exception: 'near' field must be point\"。这是什么意思,它对我的​​代码意味着什么?我尝试使用 near 作为:

near: { type:"Point", '$locations.latlong': geo.ll },

最佳答案

首先声明:我不是 Node/Mongoose 专家,所以我希望您能将通用格式翻译成 Node/Mongoose。

对于错误:

 errmsg: "exception: 'near' field must be point"

对于“2d”索引,这不能是 GeoJson点,而需要是“旧坐标对”。例如,

{
  "$geoNear": {
    "near": geo.ll,
    "maxDistance": 40000,
    "distanceField": "dist.calculated"
  }
}

如果您想使用 GeoJSON,您需要使用“2dsphere”索引。

通过该更改,$geoNear 查询将与查询中的点数组一起使用。 shell中的一个例子:

> 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
}

请注意,每个文档(最近点)只能得到一个距离,这在语义上与展开然后确定到每个点的距离不同。我不确定这对您的用例是否重要。

关于javascript - MongoDB/Mongoose - 与 geoNear 和子文档的聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29261089/

相关文章:

javascript - Angular 响应式表单 - 当子 FormGroup 更改时手动触发父 FormGroup 的验证

javascript - 将命令行输入转换为 Node Fluent ffmpeg

javascript - jQuery:删除前n个元素之后的所有元素?

c# - 将 mongodb 连接到 C#

javascript - Mongoose 使用另一个字段(即数组)的项目更新字段

javascript - 将我的 React 应用程序连接到 PHP 服务器上的 MySQL 数据库

javascript - 如何正确构建异步 Node 代码

django - Mongodb 服务器未启动

javascript - 查找文档,然后在数组中查找条目并将其从数组中删除

node.js - Mongoose withTransaction 仅部分执行