MongoDB文本搜索按多个字段过滤 [英] MongoDB text search filter by multiple fields

查看:380
本文介绍了MongoDB文本搜索按多个字段过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下文档结构.

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

我正在尝试搜索此集合,并希望按uid和/或cid过滤结果.我要运行的一些查询:

I am trying to search this collection and want to filter results by uid and/or cid. Some queries that I want to run:

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...

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

I tried to create a compound index like this

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

但是它仅适用于查询#1,如果我不提供其中一个字段,则会出现以下错误.

But it only works for query #1, if I don't supply one of the fields I get the below error.

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 =上创建非化合物索引会导致大量文档被扫描

  1. Creating non-compound indices on uid/cid = results in alot of documents being scanned

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

Moving the uid cid indices after the text index ie

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

与#1 uid和cid索引相同.

Same as #1 uid and cid index not used.

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

Info about what I am trying: http://docs.mongodb.org/manual/tutorial/limit-number-of-items-scanned-for-text-search/

我丢失了某些东西吗?或者MongoDB使用索引无法做到这一点吗?

Am I missing something or is this not possible with MongoDB using an index?

推荐答案

不仅完整记录了,而且我也发现您的断言是错误的.在可以满足您指定条件的标准样品上,结果将如下所示.但是首先是文档参考:

Not only is the expected behavior completely documented but I also find your assertion to be false. On a standard sample that could meet the conditions you specify, the results will be as shown. But first the documentation reference:

  • 如果复合文本索引在文本索引键之前包含键,则要执行$ text搜索,查询谓词必须在前面的键上包含相等匹配条件.
  • 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.

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

Then the explain output of of valid query:

{
    "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
}

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

So if you want to issue queries that have a different pattern the the "compound key" you have actually created and that meets the rules that are clearly specified then you possibly also should have payed attention to the main point:

  • 一个收藏集最多可以具有一个文本索引.
  • A collection can have at most one text index.

因此,以任何形式"的复合形式或其他形式,如果要查找MongoDB文本索引的多个定义,则不能这样做.这同样适用于地理空间"索引以及 $or 表达式,或 .sort() 查询引擎一次只能选择一个索引.

So in "any form" compound or other, if you are seeking more than one definition of a MongoDB text index then you cannot do that. The same applies to "geospatial" indexes, as well as the general consideration that outside of an $or expression, or a .sort() the query engine can only select one index at a time.

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

Modern versions should report the very specific line along with the error:

(如果文本索引为复合索引,是否为所有前缀字段都提供相等谓词?)

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

因此,所有字段都是必填字段,并且它们必须"是完全匹配项,而不能使用不等式运算符.

So "all" of the fields are required and they "must be" an exact match without using inequality operators.

如果您不打算始终"在完全匹配"条件下将其他字段用作查询的一部分,那么您将无法与文本搜索一起形成复合索引.

If you are not going to "always" use the other fields as part of your query with "exact match" conditions then you cannot form a compound index along with a text search.

这篇关于MongoDB文本搜索按多个字段过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆