Mongodb错误“无法使用文本索引来满足$ text查询”

时间:2016-03-17 09:36:16

标签: mongodb mongoose

我正在尝试使用全文搜索。以这种方式设置索引

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是'autofilled',因为它是一个鉴别器。使用单个_type的查询有效,但我不需要,我必须查询4个继承的模型。 我甚至尝试了$或者,但是没有使用相同的错误。

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)
    });

2 个答案:

答案 0 :(得分:2)

错误消息说"如果文本索引是复合的,是否为所有前缀字段给出了等式谓词?"。这意味着,在您的查询中,您必需也可以提供类型。您的查询不会这样做,因为它只使用$text部分,而不是索引的type部分。

答案 1 :(得分:0)

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

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

要解决此问题,您可以尝试首先使用通配符文本字段创建复合索引,然后再按如下所示创建其他键。

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

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

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