mongodb查询使用位置字段和其他多个字段:
{
"location": {
"$nearSphere": ["<val>"],
"$maxDistance": "<val>"
},
"userId": {
"$nin": ["<vals>"]
},
"date": {
"$gte": "<val>"
},
"age": {
"$in": ["<vals>"]
},
"property1": {
"$in": ["<vals>"]
},
"weight": {
"$in": ["<vals>"]
}
}
“位置”字段使用legacy coordinates pairs。
创建一个2dsphere
索引以便使用多个字段。
与可以引用一个位置字段的复合2d索引不同, 在另一个字段中,复合2dsphere索引可以引用多个 位置和非位置字段。
{
"count": 1,
"height": 1,
"weight": 1,
"age": 1,
"date": -1,
"location": "2dsphere",
"userId": 1
}
docs说:
$ nearSphere需要地理空间索引:
- 用于定义为GeoJSON点的位置数据的2dsphere索引
- 2d索引 用于定义为旧版坐标对的位置数据。使用二维 在GeoJSON点上建立索引,在的坐标字段上创建索引 GeoJSON对象。
还有here:
具有2dsphere索引的字段必须以以下形式保存几何数据 坐标对或GeoJSON数据。
1)会完全使用索引吗?从文档中,我了解到2dsphere
索引要求位置数据是GeoJSON
对象,而不是旧版坐标对。另一方面,也可以从旧式坐标对建立2dsphere
索引。
2)可以优化索引(或查询)吗?
答案 0 :(得分:0)
我建议您使用$ geoWithin代替$ nearSphere(如果您的用例匹配)。 $ nearsphere按照从中心点开始的距离增加的顺序对结果进行排序,而$ within则不然。如果您不需要根据距离进行排序,或者在任何其他字段上进行排序,那么没有必要使用$ nearsphere。
对于$ geoWithin来说,2dsphere索引不是强制性的,尽管性能是必需的。因此,如果在您的查询中,如果其他匹配条件还剩下一小部分结果要过滤掉以进行位置匹配,则根本不需要在位置字段上使用索引。我的观点是仅在基数非常高的那些字段上创建索引,没有必要在复合索引中添加所有字段。目前,您的复合索引中有7个字段。
1)使用mongo说明查询来检查索引是否正在使用(并在此处共享执行计划)。 2dsphere索引支持存储为GeoJSON对象和旧版坐标对的数据。对于旧式坐标对,索引会将数据转换为GeoJSON Point。
2)对于索引优化,从基数较低的索引中删除字段。复合索引中的字段顺序很重要,因此请根据相同的事实对其进行排序。我不认为(因为我不知道用例,所以不能发表太多评论),查询中还有任何改进的余地。另外,您可以从索引中删除userId,$ nin在复合索引中效果不佳。
P.S .:基数:集合中元素的数量。例如。字段“性别”只能有两个字段“ M”和“ F”,因此基数非常低。而“移动”字段具有非常不同的数字,因此具有很高的基数。如果您在复合索引中使用2dsphere索引,请首先使用它。
尝试使用最多3个字段的不同复合索引。