我有一个包含大约200K文档的集合:
db.place.find()[0]
{
"_id" : ObjectId("5290de1111afb260363aa4a1"),
"name" : "place X",
"center" : [x, y]
}
现在我试图查询中心Y大于X的地方,并遇到以下问题:
> db.place.find({'center.0':{'$gt':center.1}}).count()
Sat Nov 23 14:42:01.556 JavaScript execution failed: SyntaxError: Unexpected number
任何提示? 提前致谢
答案 0 :(得分:3)
因为您每次碰巧都有确切的字段格式(圆是一个双元素数组),您可以将它在聚合框架中转换为两个字段,然后在投影中进行比较,并匹配以获得满足的元素您对第二个数组元素的要求大于第一个数组元素。
db.place.aggregate( [
{ $unwind : "$center" },
{ $group : { _id : "$_id",
centerX : {$first:"$center"},
centerY : {$last:"$center"}
} },
{ $project : { YgtX : { $gt : [ "$centerY", "$centerX" ] } } },
{ $match : { YgtX : true } }
] );
现在,如果您的数组是一对任意数值,那么您可以使用上面的数值。
你在评论中说你的对代表坐标(lat,long) - 请记住,在MongoDB中,坐标对总是stored as long, lat - 如果你的实际x,y值是平面上的坐标(相反)到球形),您可以找到所有Y坐标大于X坐标的文档与单个地理空间查询:
db.place.find( { center : { $geoWithin : { $geometry : {
type:"Polygon",
coordinates:[[[50,50],[-50,50],[-50,-50],[50,50]]]
} } } } );
上述查询假设您的坐标系沿X和Y从-50到50,它会找到三角形中代表Y> = X的所有坐标的所有点。
答案 1 :(得分:2)
您似乎需要使用 $where 运算符。
db.place.find({$where: function() {return this.center[0] > this.center[1]}})
例如,集合中有3个文档:
{ "_id" : ObjectId("52910457c7d99f10949e5a85"), "name" : "place X", "center" : [ 2, 3 ] }
{ "_id" : ObjectId("52910463c7d99f10949e5a86"), "name" : "place Y", "center" : [ 3, 2 ] }
{ "_id" : ObjectId("5291046ac7d99f10949e5a87"), "name" : "place Y", "center" : [ 8, 9 ] }
$ where命令的结果将是:
{ "_id" : ObjectId("52910463c7d99f10949e5a86"), "name" : "place Y", "center" : [ 3, 2 ] }
答案 2 :(得分:1)
您无法在mongo中以简单的方式执行所需的查询,因为mongo不支持基于集合中的元素进行搜索或更新。所以即使是{a : 1, b : 1}
这样简单的文档,如果没有$where
子句,也找不到a = b的文档。
idbentley db.place.find({'center.0':{'$gt':'center.1'}})
建议的解决方案也不会起作用(也不会产生错误),因为这样你就可以将center.0与字符串'center.1'进行比较。因此,正确的解决方案是维多利亚马来亚的解决方案(但她忘了把.count()放在最后)。
我想建议一件事。任何地方都非常慢。因此,如果您尝试多次执行此查询,请考虑创建将存储此预先计算结果的其他字段(您可以使用this答案以类似方式执行此操作)。
答案 3 :(得分:0)
您还可以使用 $expr
运算符:https://docs.mongodb.com/manual/reference/operator/query/expr/
db.place.find({$expr: {$gt: ['$center.0', '$center.1']}}).count()
然而:类似于 $where
$expr
非常慢,请阅读此处了解详情:Mongodb $expr query is very slow