2013-11-23 141 views
1

我有一个集合约200K的文件是这样的:MongoDB中找到比较数组元素

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 

任何提示? 在此先感谢

+2

应该是:'db.place.find({'岑ter.0“:{” $ GT“:” center.1' }})数()'注意周围center.1 – idbentley

+0

我已经试过此查询的报价,但似乎这是行不通的。我正在使用版本2.4.7。我用$运算符代替了答案。 –

+0

你不能引用文档中右侧的内容(即{a:1}可以,{a:b},其中b是另一个字段不可用如果你需要比较x和y可能会认为模式不适合您的用例 - 您是否必须像这样存储x和y? –

回答

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]]] 
} } } }); 

上面的查询假设您的坐标系从-50变为50沿X和Y,它会找出在三角形代表具有Y> = X.所有坐标的所有点

+3

酷!非常意外的解决方案:) –

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

其中command将是$结果:

{ "_id" : ObjectId("52910463c7d99f10949e5a86"), "name" : "place Y", "center" : [ 3, 2 ] } 
+1

你好维多利亚,谢谢你的回应..正如萨尔瓦多达利所说,这不是一个表演性的解决方案......将继续寻找更快的方式。 –

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答案做一个类似的方式)。