【问题标题】:mongo db create accurate indexmongodb 创建准确的索引
【发布时间】:2014-12-02 22:18:21
【问题描述】:

我想为以下查询创建一个 mongodb 索引:

{
  "$and": [
    {
      "$or": [
        {
          "connector_name": {
            "$options": "i",
            "$regex": "plop"
          }
        },
        {
          "connector": {
            "$options": "i",
            "$regex": "plop"
          }
        },
        {
          "component": {
            "$options": "i",
            "$regex": "plop"
          }
        },
        {
          "resource": {
            "$options": "i",
            "$regex": "plop"
          }
        },
        {
          "domain": {
            "$options": "i",
            "$regex": "plop"
          }
        },
        {
          "perimeter": {
            "$options": "i",
            "$regex": "plop"
          }
        }
      ]
    },
    {
      "$or": [
        {
          "event_type": {
            "$eq": "check"
          }
        }
      ]
    }
  ]
}

我尝试了以下索引创建失败:

第一个索引尝试:

db.events.ensureIndex({'event_type': 1});
db.events.ensureIndex({'connector_name': 1});
db.events.ensureIndex({'connector': 1});
db.events.ensureIndex({'component': 1});
db.events.ensureIndex({'resource': 1});
db.events.ensureIndex({'domain': 1});
db.events.ensureIndex({'perimeter': 1});

第二个索引尝试:

db.events.ensureIndex({'event_type': 1, 'connector_name': 1});
db.events.ensureIndex({'event_type': 1, 'connector': 1});
db.events.ensureIndex({'event_type': 1, 'component': 1});
db.events.ensureIndex({'event_type': 1, 'resource': 1});
db.events.ensureIndex({'event_type': 1, 'domain': 1});
db.events.ensureIndex({'event_type': 1, 'perimeter': 1});

第三个索引尝试:

db.events.ensureIndex(
{
    'event_type': 1,
    'connector_name': 1,
    'connector': 1,
    'component': 1,
    'resource': 1,
    'domain': 1,
    'perimeter': 1,
})

每次在mongo explain query 之后,我都会查看“indexOnly”和“nscanned”字段,这意味着(据我所知)mongo 对我的索引的良好使用。但是,到目前为止,结果很差,我的查询仍然没有使用索引。经过我所有的尝试,我仍然不明白我的 mongodb 索引系统哪里错了。

【问题讨论】:

  • 您正在使用不区分大小写的正则表达式匹配,这将始终导致完整的索引扫描(充其量)......并且使用$or 子句,nscanned 值将加起来为基数您正在比较的所有字段中。您能否描述一下您实际需要搜索的内容 - 只是关键字,还是您需要在所有这些字段中进行子字符串匹配?
  • 通过这个查询,我想找到所有包含查询值的匹配文档,这里是 "plop" 。现在,我将尝试按照您的建议进行区分大小写的搜索,希望 mongo 将使用我的索引。事实上,这个查询的目的是在我的文档中执行搜索以及搜索引擎。这就是为什么我的搜索如此宽松。
  • 我更改了查询,现在它看起来像 "$or": [ { "connector_name": { "$regex": "/^Sphinx.*/" } },...我之前描述的第三个索引模型,但索引搜索仍然无法正常工作

标签: mongodb indexing database


【解决方案1】:
db.collection.ensureIndex({connectorname:"text",connector:"text",component:"text"...})

这会在字段上创建一个文本索引。然后,你可以像这样查询

db.collection.find({$or:[{$text:{$search:"plop"},{event_type:"check"}]})

这将返回在为其创建文本索引的字段中包含搜索词或具有 event_type == "check" 的所有文档。

详情请见the MongoDB docs on "Text Indices"

【讨论】:

  • 你好 Markus,文本字段在我的情况下无法正常工作,如 mongo 文档中所述:text indices 一个集合最多可以有一个文本索引。但是,我需要就我而言,其中有许多搜索字段
  • 我对文档了如指掌。为什么需要多个文本索引?只需创建一个复合索引,如图所示。您可以使用聚合而不是查询来排除在不需要的字段中包含搜索词的文档。
猜你喜欢
  • 2011-08-20
  • 2017-04-13
  • 2011-03-20
  • 2020-10-08
  • 2012-12-09
  • 1970-01-01
  • 2015-11-08
  • 2014-04-14
  • 1970-01-01
相关资源
最近更新 更多