MongoDB 按多个字段过滤文本搜索

MongoDB text search filter by multiple fields

我有以下文档结构。

{
   content: 'cat dog bird',
   uid: <another_unique_id>
   cid: <another_unique_id>
}

我正在尝试搜索此集合并希望按 uid and/or cid 筛选结果。我想要的一些查询 运行:

1) db.mycollection.find({uid: '1', cid: '2', $text: {$search: 'cat'}});         
2) db.mycollection.find({cid: '2', $text: {$search: 'cat'}});
3) db.mycollection.find({uid: '1', $text: {$search: 'cat'}});
4) db.mycollection.find({$text: {$search: 'cat'}});
//etc...

我试过创建这样的复合索引

db.mycollection.ensureIndex({uid: 1, cid: 1, content: 'text'});

但它只适用于查询 #1,如果我不提供其中一个字段,我会收到以下错误。

planner returned error: failed to use text index to satisfy $text query 
(if text index is compound, are equality predicates given for all prefix fields?)

我尝试的其他事情:

  1. uid/cid 上创建非复合索引 = 导致扫描大量文档

  2. uid cid 索引移动到文本索引之后,即

    db.mycollection.ensureIndex({content: 'text', uid: 1, cid: 1});

    与#1 相同,未使用 uid 和 cid 索引。

关于我正在尝试的信息: http://docs.mongodb.org/manual/tutorial/limit-number-of-items-scanned-for-text-search/

我是不是遗漏了什么,或者 MongoDB 使用索引是不可能的?

不仅是预期的行为 completely documented,而且我还发现您的断言是错误的。在满足您指定条件的标准样品上,结果将如图所示。但首先是文档参考:

  • If the compound text index includes keys preceding the text index key, to perform a $text search, the query predicate must include equality match conditions on the preceding keys.

然后有效查询的解释输出:

{
    "queryPlanner" : {
       "plannerVersion" : 1,
       "namespace" : "test.mycollection",
       "indexFilterSet" : false,
       "parsedQuery" : {
           "$and" : [
               {
                   "cid" : {
                       "$eq" : 2
                   }
               },
               {
                   "uid" : {
                       "$eq" : 1
                   }
               },
               {
                   "$text" : {
                       "$search" : "cat",
                       "$language" : ""
                   }
               }
          ]
      },
      "winningPlan" : {
          "stage" : "TEXT",
          "indexPrefix" : {
               "uid" : 1,
               "cid" : 2
          },
          "indexName" : "uid_1_cid_1_content_text",
          "parsedTextQuery" : {

          }
      },
      "rejectedPlans" : [ ]
  },
  "serverInfo" : {
      "host" : "trashbox",
       "port" : 27017,
       "version" : "3.0.0",
       "gitVersion" : "a841fd6394365954886924a35076691b4d149168"
  },
  "ok" : 1
}

因此,如果您想发出与您实际创建的 "compound key" 具有不同模式并且符合明确指定的规则的查询,那么您可能还应该注意要点:

  • A collection can have at most one text index.

所以在 "any form" 复合或其他中,如果您正在寻找 MongoDB 文本索引的多个定义,那么您不能这样做。这同样适用于 "geospatial" 索引,以及在 $or expression, or a .sort() 之外的一般考虑,查询引擎一次只能 select 一个索引。

现代版本应该报告非常具体的行以及错误:

(if text index is compound, are equality predicates given for all prefix fields?)

因此 "all" 个字段是必需的,它们 "must be" 完全匹配,无需使用不等运算符。

如果您不打算 "always" 使用其他字段作为带有 "exact match" 条件的查询的一部分,那么您不能在文本搜索的同时形成复合索引。