【问题标题】:$and combined with 2dsphere in mongo/mongoose$and 与 mongo/mongoose 中的 2dsphere 结合
【发布时间】:2014-07-14 06:13:10
【问题描述】:

我正在尝试让这段代码工作(节点+猫鼬)

model.find({
        $and: [
            { 'location': { $near: { $geometry: {type: 'Point', coordinates: [lat, long]}  }, $maxDistance: 1000 }},
            {'status': { $size: 1 }}
        ]
    },

继续努力

找不到任何特殊索引:2d(需要索引)、2dsphere(需要 索引),对于: { $and: [ { location: { $near: { $geometry: { type: “点”,坐标:[ 12.5386, 41.884 ] } },$maxDistance:1000 } }, { 状态:{ $size: 1 } } ] }

我确实有我的索引与 mongo

{
    "location" : "2dsphere"
}

我错过了什么? 非常感谢。

编辑:添加文档结构

{
    "name" : "Frag",
    "desc" : "Frag",
    "host" : ObjectId("534047663164711f7e7a952f"),
    "_id" : ObjectId("535d7d8b454017f874de2d42"),
    "status" : [ 
        {
            "state" : "created",
            "_id" : ObjectId("535d7d8b454017f874de2d43"),
            "date" : ISODate("2014-04-27T21:58:35.406Z")
        }
    ],
    "users" : [ 
        ObjectId("534047663164711f7e7a952f")
    ],
    "location" : [ 
        32.0652823, 
        34.7767135
    ],
    "__v" : 0
}

【问题讨论】:

  • $and 隐含在所有 MongoDB 查询中。您无需将其指定为包装器。也许在您的问题中显示文档。 location 真的是顶级字段吗?
  • 感谢您的帮助,已添加到问题中
  • 当然。 “位置”在哪里?它不在您的文档中。因为这看起来你在这里有很多参考,它实际上是在另一个集合中吗?即使您指定了其他集合文档的正确路径,除非嵌入了该数据,否则您无法执行此查询。似乎您需要了解 Mongoose populate 的局限性以及它实际上可以做什么。或者不按照可能的情况去做。
  • 哎呀我的坏。错误的复制粘贴,但我确实注意到我的一些文件缺少“位置”,这可能是问题吗?虽然如果我在 find 中不包含“status.size”会很奇怪,但它工作得很好。

标签: node.js mongodb mongoose


【解决方案1】:

您在这里做错了,因为您正在为您实际定义为“旧坐标对”的东西指定 GeoJSON 坐标映射,并且两者之间存在很大差异。

当然你应该做什么(你在我的集合中的数据称为 docs):

db.docs.find({ 
    "location": { 
        "$near": [12.5386, 41.884], 
        "$maxDistance": 1000
    },
    "status": { "$size": 1 }
})

但这会失败,除非我实际上将索引类型更改为“2d”:

db.docs.dropIndexes();
db.docs.ensureIndex({ "location": "2d" })

然后你得到你所期望的文档结果。

这是设计使然,因为“2dsphere”索引是为 GeoJSON 格式的数据设计的,来自文档:

$near 运算符需要地理空间索引:GeoJSON 点的 2dsphere 索引;旧坐标对的二维索引。默认情况下,使用 2d 索引的查询返回 100 个文档的限制;但是你可以使用 limit() 来改变结果的数量。

如果您想要一个“2dsphere”索引,那么您的坐标数据需要更改:

    "loc" : {
        "type" : "Point",
        "coordinates" : [
            32.0652823, 
            34.7767135
        ]
    }

但直接的“解决方法”显然是改用“2d”索引,当然,正如我所展示的那样改变你的语法。

【讨论】:

  • 这很奇怪;我添加了 {"location" : "2d"} 并使用了您建议的查询,但现在 $maxdistance 根本不起作用!它总是返回仅由 status.size 过滤的所有文档,这也是一个错误吗?仅供参考,我在 2.4.3 上。
  • @Pavel'PK'Kaminsky $maxdistance 是一个错字。应该是$maxDistance。还要检查您是否确实有超出您要求的范围的点。但我无法重现。索引类型是设计使然。请参阅答案中的进一步说明。
猜你喜欢
  • 2016-07-24
  • 2012-11-03
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 2012-10-27
  • 2013-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多