如何用Mongo java驱动程序编写与索引交集的查询

时间:2014-09-18 15:33:25

标签: java mongodb indexing

我用谷歌搜索并阅读mongodb(http://docs.mongodb.org/manual/core/index-intersection/)的官方文档,但没有找到任何关于使用索引交集的查询语法的教程或指示。

当查询涉及由单个索引单独索引的2个字段时,mongodb是否自动应用索引交集?我不这么认为。

当我在2个日期和给定的“名称”之间运行查询时,以下是cursor.explain()显示的内容(“name”是一个字段,日期和名称都被编入索引。)

{
  "cursor": "BtreeCursor Name_1",
  "isMultiKey": false,
  "n": 99330,
  "nscannedObjects": 337500,
  "nscanned": 337500,
  "nscannedObjectsAllPlans": 337601,
  "nscannedAllPlans": 337705,
  "scanAndOrder": false,
  "indexOnly": false,
  "nYields": 18451,
  "nChunkSkips":
  "millis": 15430,
  "indexBounds": {
    "Name": [
      [
        "blabla",
        "blabla"
      ]
    ]
  },
  "allPlans": [
    {
      "cursor": "BtreeCursor Name_1",
      "isMultiKey": false,
      "n": 99330,
      "nscannedObjects": 337500,
      "nscanned": 337500,
      "scanAndOrder": false,
      "indexOnly": false,
      "nChunkSkips": 0,
      "indexBounds": {
        "Name": [
          [
            "blabla",
            "blabla"
          ]
        ]
      }
    },
    {
      "cursor": "BtreeCursor Date_1",
      "isMultiKey": false,
      "n": 0,
      "nscannedObjects": 101,
      "nscanned": 102,
      "scanAndOrder": false,
      "indexOnly": false,
      "nChunkSkips": 0,
      "indexBounds": {
        "Date": [
          [
            "2014-08-23 10:28:50.221",
            "2014-08-23 13:28:50.221"
          ]
        ]
      }
    },
    {
      "cursor": "Complex Plan",
      "n": 0,
      "nscannedObjects": 0,
      "nscanned": 103,
      "nChunkSkips": 0
    }

复杂的计划没有显示任何内容。经过的时间是16秒。如果我只按名称查询没有日期,则只需0.9秒

我想学习如何使用mongojava驱动程序中的索引交集编写查询,类似于mongo shell中的hint()。欢迎任何示例或教程链接。

我知道用Mongodb java驱动程序编写基本查询。如果能节省您的时间,您可以发布基本代码示例。

提前致谢。

2 个答案:

答案 0 :(得分:4)

阅读完这些链接后:http://docs.mongodb.org/manual/core/query-plans/#index-filters https://jira.mongodb.org/browse/SERVER-3071

我得出结论,现在没办法强制查询使用索引交集。

事实上,当一个候选索引可以用于查询时,mongodb并行运行它们并等待索引以赢得匹配"。获胜者索引是首先完成整个查询或首先返回阈值数量的匹配结果的索引。然后mongodb使用此索引进行查询。

如果您的查询非常不同并且您无法构建许多复合索引,那么它就死了。你只能相信mongodb的测试。

有时,一个指数比另一个指数更具选择性。但这并不意味着它会更快地返回结果。就像我的情况一样," name"索引更具选择性。它可能会获取更少的文档。但它需要一个日期比较来确定所获取的文档是否与整个查询匹配。另一方面," date" index从disque中获取更多文档,但只对" name"进行简单的相等测试。用于确定文档是否与查询匹配的字段。这可能是为什么它可以赢得测试的原因。

关于索引交集,它从未在我的几个查询测试中使用过。我怀疑它是否有用并期望mongodb在未来的版本中提高其性能。

如果我的结论有误,请指出。还在学习MongoDB:)

答案 1 :(得分:1)

  

mongodb在查询时是否自动应用索引交集   涉及2个字段,这些字段由单个索引单独索引?

已在此处回答:MongoDB index intersection

您无法强制MongoDB应用索引交集,而是可以修改查询以允许MongoDB查询优化器在您的查询中应用index intersection策略。

要了解查询参数如何影响索引过程,请参阅此链接,尽管它适用于复合索引。

http://java.dzone.com/articles/optimizing-mongodb-compound

Java API提供了两种方法来将hint()与find()操作一起使用:

  

MongoDB Java API

     

public DBCursor hint(String indexName)

     

public DBCursor提示(DBObject indexKeys)

     

向数据库通知集合的索引字段   提高绩效。

可以使用如下,

List obj = collection.find( query ).hint(indexName);