【问题标题】:Mongodb error "failed to use text index to satisfy $text query"Mongodb错误“未能使用文本索引来满足$文本查询”
【发布时间】:2020-05-10 18:45:43
【问题描述】:

我正在尝试使用全文搜索。这样设置索引

myRootSchema.index({ "_type": 1, "$**": "text" }); 

其中 _type 是一个 discriminatorKey,myRootSchema 是 4 个继承模式的父模式。

我收到此错误

{
"name": "MongoError",
"message": "error processing query: ns=MYDB.caseNotesTree: TEXT : query=title, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL\nSort: {}\nProj: {}\n 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?)",
"waitedMS": 0,
"ok": 0,
"errmsg": "error processing query: ns=MYDB.caseNotesTree: TEXT : query=title, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL\nSort: {}\nProj: {}\n 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?)",
"code": 2
}

尝试这个查询

Model
    .find(
        { $text : { $search :req.query.q } }

    )
    .exec(function(err, data) {
        if(err)res.json(err)
        res.json(data)
    });

编辑: 按照建议,我应该在查询中设置 _type 字段,但 _type 是“自动填充的”,因为它是一个鉴别器。具有单个 _type 的查询有效,但我不需要,我必须查询 4 ​​个继承模型。 我什至尝试了 $or,但没有出现同样的错误。

Model
    .find(
        {   $or: [ { _type: 'childA' },
            { _type: 'childB' },
            { _type: 'childC' },
            { _type: 'childD' }
        ], $text : { $search :req.query.q } }

    )
    .exec(function(err, data) {
        if(err)console.log(err)
        res.json(data)
    });

【问题讨论】:

  • Combine full text with other index 的可能副本,它实际上回答了问题,而不仅仅是引用文档。
  • Model 是您的根模型还是您的 4 个继承模式之一的模型?
  • 对,_type 只会添加到您对继承模型的查询中。而不是$or,您是否尝试添加_type: {$in: ['childA', 'childB', 'childC', 'childD']}
  • 不行,我刚试过,不行。
  • 那么我认为您不能在使用$text 查询的同时查询多个_type 值,考虑到复合索引的构造方式,这很有意义。您需要分别$text 查询每个_type,然后将结果合并在一起;有效地创建您自己的$or 查询。

标签: mongodb mongoose


【解决方案1】:

错误消息显示“如果文本索引是复合的,是否为所有前缀字段提供相等谓词?”。这意味着,在您的查询中,您也需要提供类型。您的查询不会这样做,因为它只使用索引的 $text 部分,而不是 type 部分。

【讨论】:

  • 不一定正确。该问题提到了“鉴别器”,这是填充 _type 字段的位置。 Mongoose“自动”(喜欢这个词)使用分配给鉴别器的模型发出的所有查询的确切值(相等前缀)。因此,在将_type 发送到服务器之前为您填写时,您无需在查询中明确包含_type。在此处的另一个答案中也已经涵盖了复合文本索引的问题。
  • 很抱歉,我阅读了整篇文章,但我不明白我的判别器情况如何。正如您正确指出的那样,由鉴别器和通配符文本组成的复合索引。请参考我的编辑。
【解决方案2】:

这是 MongoDB 中“文本”索引的限制。根据通配符文本索引的 mongoDB 文档,如果有任何前面的键,则查询谓词必须在前面的键上包含相等匹配条件。有关文档,请参阅 here

修改后的代码位$or: [ { _type: 'childA' },{ _type: 'childB' },{ _type: 'childC' },{ _type: 'childD' } 可以看作_type: {$in: ['childA', 'childB', 'childC', 'ChildD']},它与指定的限制不匹配,即必须存在相等条件。

要克服这个问题,您可以尝试使用通配符文本字段创建复合索引,然后是其他键,如下所示。

myRootSchema.index({ "$**": "text" , "_type": 1}); 

这很好用。但它没有优化。

如果您正在考虑优化查询,那么您必须在两个不同的查询中分别使用过滤器,直到 Mongo 放宽限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-07
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    相关资源
    最近更新 更多