MongoDB 索引文本搜索仅适用于完全匹配

MongoDB indexed text search only works for exact match

我在字段 'user_name' 中填充了数据。 此代码没有给我任何结果:

history = db.history
history.create_index([('user_name', 'text')])
history.find({'$text' : {'$search' : 'a'}})

但是当我指定确切的名称时,它起作用了

history.find({'$text' : {'$search' : 'exact name'}})

这是 'a' 搜索的 explain() 的输出:

{
    "executionSuccess": true,
    "nReturned": 0,
    "executionTimeMillis": 0,
    "totalKeysExamined": 0,
    "totalDocsExamined": 0,
    "executionStages": {
        "stage": "TEXT",
        "nReturned": 0,
        "executionTimeMillisEstimate": 0,
        "works": 1,
        "advanced": 0,
        "needTime": 0,
        "needYield": 0,
        "saveState": 0,
        "restoreState": 0,
        "isEOF": 1,
        "indexPrefix": {},
        "indexName": "user_name_text",
        "parsedTextQuery": { "terms": [], "negatedTerms": [], "phrases": [], "negatedPhrases": [] },
        "textIndexVersion": 3,
        "inputStage": {
            "stage": "TEXT_MATCH",
            "nReturned": 0,
            "executionTimeMillisEstimate": 0,
            "works": 0,
            "advanced": 0,
            "needTime": 0,
            "needYield": 0,
            "saveState": 0,
            "restoreState": 0,
            "isEOF": 1,
            "docsRejected": 0,
            "inputStage": {
                "stage": "FETCH",
                "nReturned": 0,
                "executionTimeMillisEstimate": 0,
                "works": 0,
                "advanced": 0,
                "needTime": 0,
                "needYield": 0,
                "saveState": 0,
                "restoreState": 0,
                "isEOF": 1,
                "docsExamined": 0,
                "alreadyHasObj": 0,
                "inputStage": { "stage": "OR", "nReturned": 0, "executionTimeMillisEstimate": 0, "works": 0, "advanced": 0, "needTime": 0, "needYield": 0, "saveState": 0, "restoreState": 0, "isEOF": 1, "dupsTested": 0, "dupsDropped": 0 }
            }
        }
    },
    "allPlansExecution": []
}

这是用户名 ('akkcess') 完全匹配的 explain() 的输出:

{
    "executionSuccess": true,
    "nReturned": 39,
    "executionTimeMillis": 1,
    "totalKeysExamined": 39,
    "totalDocsExamined": 39,
    "executionStages": {
        "stage": "TEXT",
        "nReturned": 39,
        "executionTimeMillisEstimate": 0,
        "works": 40,
        "advanced": 39,
        "needTime": 0,
        "needYield": 0,
        "saveState": 0,
        "restoreState": 0,
        "isEOF": 1,
        "indexPrefix": {},
        "indexName": "user_name_text",
        "parsedTextQuery": { "terms": ["akkcess"], "negatedTerms": [], "phrases": [], "negatedPhrases": [] },
        "textIndexVersion": 3,
        "inputStage": {
            "stage": "TEXT_MATCH",
            "nReturned": 39,
            "executionTimeMillisEstimate": 0,
            "works": 40,
            "advanced": 39,
            "needTime": 0,
            "needYield": 0,
            "saveState": 0,
            "restoreState": 0,
            "isEOF": 1,
            "docsRejected": 0,
            "inputStage": {
                "stage": "FETCH",
                "nReturned": 39,
                "executionTimeMillisEstimate": 0,
                "works": 40,
                "advanced": 39,
                "needTime": 0,
                "needYield": 0,
                "saveState": 0,
                "restoreState": 0,
                "isEOF": 1,
                "docsExamined": 39,
                "alreadyHasObj": 0,
                "inputStage": {
                    "stage": "OR",
                    "nReturned": 39,
                    "executionTimeMillisEstimate": 0,
                    "works": 40,
                    "advanced": 39,
                    "needTime": 0,
                    "needYield": 0,
                    "saveState": 0,
                    "restoreState": 0,
                    "isEOF": 1,
                    "dupsTested": 39,
                    "dupsDropped": 0,
                    "inputStage": {
                        "stage": "IXSCAN",
                        "nReturned": 39,
                        "executionTimeMillisEstimate": 0,
                        "works": 40,
                        "advanced": 39,
                        "needTime": 0,
                        "needYield": 0,
                        "saveState": 0,
                        "restoreState": 0,
                        "isEOF": 1,
                        "keyPattern": { "_fts": "text", "_ftsx": 1 },
                        "indexName": "user_name_text",
                        "isMultiKey": false,
                        "isUnique": false,
                        "isSparse": false,
                        "isPartial": false,
                        "indexVersion": 2,
                        "direction": "backward",
                        "indexBounds": {},
                        "keysExamined": 39,
                        "seeks": 1,
                        "dupsTested": 0,
                        "dupsDropped": 0
                    }
                }
            }
        }
    },
    "allPlansExecution": []
}

你知道它为什么会这样吗? 根据文档和教程,这应该有效。

“a”几乎可以肯定是 stop word。几乎每个自然语言文本都会包含它。因此,如果搜索它,您将获得结果集中的每一个文档。由于这不是很有用,文本搜索会从查询中删除诸如“a”之类的停用词。

另外,MongoDB 文本搜索 确实 包含完全匹配功能,但它需要引用您尚未执行的查询,因此您使用的是常规在您发布的查询中进行了词干匹配,而不是完全匹配。