为什么$ in比$ all快得多?

时间:2012-09-11 07:01:03

标签: mongodb indexing

db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.053980478460939611 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^soto/, /^nasi/] } }).limit(200);

db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.053980478460939611 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$in" : [/^soto/, /^nasi/] } }).limit(200);

这是结果

/* 88 */
{
  "ts" : ISODate("2012-09-11T06:57:26.801Z"),
  "op" : "query",
  "ns" : "newisikota.tablebusiness",
  "query" : {
    "LongitudeLatitude" : {
      "$nearSphere" : [106.772835, -6.186753],
      "$maxDistance" : 0.053980478460939611
    },
    "Prominent" : {
      "$gte" : 15.0
    },
    "indexContents" : {
      "$all" : [/^soto/, /^nasi/]
    }
  },
  "ntoreturn" : 200,
  "nscanned" : 48,
  "nreturned" : 48,
  "responseLength" : 60002,
  "millis" : 3821,
  "client" : "127.0.0.1",
  "user" : ""
}

/* 89 */
{
  "ts" : ISODate("2012-09-11T06:57:43.147Z"),
  "op" : "query",
  "ns" : "newisikota.tablebusiness",
  "query" : {
    "LongitudeLatitude" : {
      "$nearSphere" : [106.772835, -6.186753],
      "$maxDistance" : 0.053980478460939611
    },
    "Prominent" : {
      "$gte" : 15.0
    },
    "indexContents" : {
      "$in" : [/^soto/, /^nasi/]
    }
  },
  "ntoreturn" : 200,
  "nscanned" : 200,
  "nreturned" : 200,
  "responseLength" : 249598,
  "millis" : 320,
  "client" : "127.0.0.1",
  "user" : ""
}

注意:$ all查询可能偶尔运行26秒。

解释结果如下:

db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.053980478460939611 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^soto/, /^nasi/] } }).limit(200).explain();




{
        "cursor" : "GeoSearchCursor",
        "nscanned" : 48,
        **"nscannedObjects" : 48,**
        "n" : 48,
        "millis" : 8563,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
        }
}
>


db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.053980478460939611 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$in" : [/^soto/, /^nasi/] } }).limit(200).explain();
{
        "cursor" : "GeoSearchCursor",
        "nscanned" : 200,
        **"nscannedObjects" : 200,**
        "n" : 200,
        "millis" : 516,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
        }
}

请注意,$ in search会扫描更多对象。

最糟糕的是,mongdob可以在搜索中做$,然后过滤掉事情。这个比例不应该很大。

2 个答案:

答案 0 :(得分:4)

您正在将苹果与橙子进行比较。两个查询返回不同的结果。 $ all表示字段值应与所有输入匹配,而$ in表示字段值应与任何一个值匹配。 $ all是和,$ in是或。

结合$ limit - $ all查询需要查看更多文档才能找到匹配项。

答案 1 :(得分:0)

我在Why using $all in mongodb is much slower?

中提出了类似的问题

这次我只用了一个字。因此,$ in和$ all之间应该没有区别。它们都是等价的。

仍然全部都要慢得多。

事实证明,根据答案,mongodb本身就存在一个错误。

https://jira.mongodb.org/browse/SERVER-1748

我想在修复问题之前我根本不会使用$ all。

对于所有其他答案,你试过这个自己吗?