简体   繁体   English

具有地理位置的Mongo复合索引不起作用

[英]Mongo compound index with geo location not working

I am having hard time with something that supposed to be trivial.... 我很难接受一些本来应该是琐碎的事情。
I have the following profile document structure: 我具有以下配置文件文档结构:

 {
   pid:"profileId",
   loc : {
       "lat" : 32.082156661684621,
       "lon" : 34.813229013156551,
       "locTime" : NumberLong(0)
         }
   age:29
 }

A common use-case in my app is to retrieve nearby profiles filtered by age. 我的应用程序中的一个常见用例是检索按年龄过滤的附近个人资料。

   { "loc" : { "$near" : [ 32.08290052711715 , 34.80888522811172] , "$maxDistance" :    179.98560115190784}, "age" : { "$gte" : 0 , "$lte" : 33}}

So I have created the following compound index: 因此,我创建了以下复合索引:

  { 'loc':2d , age:1}

And no matter what I do I can't make the query run with the created index (also tried with hint) 而且,无论我做什么,我都无法使用创建的索引来运行查询(也尝试使用提示)
this is the generated explain for the query: 这是为查询生成的解释:

  { 
  "cursor" : "GeoSearchCursor" , 
  "isMultiKey" : false , 
  "n" : 4 , 
  "nscannedObjects" : 4 , 
  "nscanned" : 4 , 
  "nscannedObjectsAllPlans" : 4 , 
  "nscannedAllPlans" : 4 , 
  "scanAndOrder" : false , 
  "indexOnly" : false , 
  "nYields" : 0 , 
  "nChunkSkips" : 0 , 
  "millis" : 0 , 
  "indexBounds" : { } ,
  "allPlans" : [ { "cursor" : "GeoSearchCursor" , "n" : 4 , "nscannedObjects" : 4 , "nscanned" :    4 , "indexBounds" : { }
  }

I am using mongodb version 2.4.4. 我正在使用mongodb 2.4.4版。

What am I doing wrong? 我究竟做错了什么? your answer is highly appreciated. 非常感谢您的回答。

The explain output says "cursor" : "GeoSearchCursor". 说明输出说“ cursor”:“ GeoSearchCursor”。 This indicates your query used a geospatial index. 这表明您的查询使用了地理空间索引。

See the following for details: http://docs.mongodb.org/manual/reference/method/cursor.explain/ 有关详细信息,请参见以下内容: http : //docs.mongodb.org/manual/reference/method/cursor.explain/

2d indexes support a compound index with only one additional field, as a suffix of the 2d index field. 2d索引仅支持一个附加字段的复合索引,作为2d索引字段的后缀。 http://docs.mongodb.org/manual/applications/geospatial-indexes http://docs.mongodb.org/manual/applications/geospatial-indexes

As @stennie mentioned in the comment on your question the problem might be the ordering of the coordinates. 正如@stennie在对您的问题的评论中提到的那样,问题可能是坐标的排序。 They should be ordered long, lat. 他们应该被命令长,拉特。 If that doesn't work try storing the loc as an array with long first element, lat second. 如果这样不起作用,请尝试将loc存储为第一个元素较长(第二个元素较长)的数组。

Here is a worked example: 这是一个工作示例:

I created three profile objects with location as array and the locTime separate from loc. 我创建了三个配置文件对象,它们的位置为数组,并且locTime与loc分开。

> db.profile.find()
{ "_id" : ObjectId("52cd54f1c43bb3a468b9fd0d"), "loc" : [  -6,  50 ], "age" : 29, "pid" : "001", "locTime" : NumberLong(0) }
{ "_id" : ObjectId("52cd5507c43bb3a468b9fd0f"), "loc" : [  -6,  53 ], "age" : 30, "pid" : "002", "locTime" : NumberLong(1) }
{ "_id" : ObjectId("52cd5515c43bb3a468b9fd10"), "loc" : [  -1,  51 ], "age" : 31, "pid" : "003", "loctime" : NumberLong(2) }

Finding using large distance and age 使用长距离和大年龄来寻找

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 5}, "age" : { "$gte" : 0 , "$lte" : 33}})
{ "_id" : ObjectId("52cd5515c43bb3a468b9fd10"), "loc" : [  -1,  51 ], "age" : 31, "pid" : "003", "loctime" : NumberLong(2) }
{ "_id" : ObjectId("52cd54f1c43bb3a468b9fd0d"), "loc" : [  -6,  50 ], "age" : 29, "pid" : "001", "locTime" : NumberLong(0) }

The explain shows the index is being used: 说明显示索引正在被使用:

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 5}, "age" : { "$gte" : 0 , "$lte" : 33}}).explain()
{
    "cursor" : "GeoSearchCursor",
    "isMultiKey" : false,
    "n" : 2,
    "nscannedObjects" : 2,
    "nscanned" : 2,
    "nscannedObjectsAllPlans" : 2,
    "nscannedAllPlans" : 2,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {

    },
}

Narrow the distance with the same age range 缩小相同年龄段的距离

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" : 1}, "age" : { "$gte" : 0 , "$lte" : 33}})

Here is the explain, again the index is used: 这里是解释,再次使用索引:

> db.profile.find({ "loc" : { "$near" : [ -1, 50] , "$maxDistance" :     1}, "age" : { "$gte" : 0 , "$lte" : 33}}).explain()
{
    "cursor" : "GeoSearchCursor",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,
    "nscannedObjectsAllPlans" : 1,
    "nscannedAllPlans" : 1,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {

    },
}

Here are the indexes: 以下是索引:

> db.profile.getIndices()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "test.profile",
        "name" : "_id_"
    },
    {
        "v" : 1,
        "key" : {
            "loc" : "2d",
            "age" : 1
        },
        "ns" : "test.profile",
        "name" : "loc_2d_age_1"
    }
]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM