2017-08-10 81 views
0

mongo3.4.6mongodb文本索引不工作

嗨出口,我是新来的mongodb,我有一些索引问题。下面我创建的requestId(串)recordInfo集合内的文本索引:

db.getCollection( “RecordInfo”)上的createIndex({ “请求ID”: “文本”})

但是当我尝试以下查询:

db.getCollection( “RecordInfo”)找到({ “请求ID”: “4513456313212313212aaaa”})解释( “executionStats”),你可以看到它不使用索引:

"executionStats" : { 
    "executionSuccess" : true, 
    "nReturned" : 1, 
    "executionTimeMillis" : 17, 
    "totalKeysExamined" : 0, 
    "totalDocsExamined" : 9998, 
    "executionStages" : { 
     "stage" : "COLLSCAN", 
     "filter" : { 
      "RequestId" : { 
       "$eq" : "4513456313212313212aaaa" 
      } 
     }, 
     "nReturned" : 1, 
     "executionTimeMillisEstimate" : 21, 
     "works" : 10000, 
     "advanced" : 1, 
     "needTime" : 9998, 
     "needYield" : 0, 
     "saveState" : 78, 
     "restoreState" : 78, 
     "isEOF" : 1, 
     "invalidates" : 0, 
     "direction" : "forward", 
     "docsExamined" : 9998 
    } 
}, 

然后我尝试下面的$ text:

db.getCollection( “RecordInfo”)找到({$文字:{$搜索: “4513456313212313212aaaa”}})。解释( “executionStats” ) 它给了我下面,我觉得相当不错的:

"executionStats" : { 
    "executionSuccess" : true, 
    "nReturned" : 1, 
    "executionTimeMillis" : 1, 
    "totalKeysExamined" : 1, 
    "totalDocsExamined" : 1, 
    "executionStages" : { 
     "stage" : "TEXT", 
     "nReturned" : 1, 
     "executionTimeMillisEstimate" : 0, 
     "works" : 5, 
     "advanced" : 1, 
     "needTime" : 3, 
     "needYield" : 0, 
     "saveState" : 0, 
     "restoreState" : 0, 
     "isEOF" : 1, 
     "invalidates" : 0, 
     "indexPrefix" : { 
     }, 
     "indexName" : "RequestId_text", 
     "parsedTextQuery" : { 
      "terms" : [ 
       "4513456313212313212aaaa" 
      ], 
      "negatedTerms" : [ ], 
      "phrases" : [ ], 
      "negatedPhrases" : [ ] 
     }, 
     "textIndexVersion" : 3, 
     "inputStage" : { 
      "stage" : "TEXT_MATCH", 
      "nReturned" : 1, 
      "executionTimeMillisEstimate" : 0, 
      "works" : 5, 
      "advanced" : 1, 
      "needTime" : 3, 
      "needYield" : 0, 
      "saveState" : 0, 
      "restoreState" : 0, 
      "isEOF" : 1, 
      "invalidates" : 0, 
      "docsRejected" : 0, 
      "inputStage" : { 
       "stage" : "TEXT_OR", 
       "nReturned" : 1, 
       "executionTimeMillisEstimate" : 0, 
       "works" : 5, 
       "advanced" : 1, 
       "needTime" : 3, 
       "needYield" : 0, 
       "saveState" : 0, 
       "restoreState" : 0, 
       "isEOF" : 1, 
       "invalidates" : 0, 
       "docsExamined" : 1, 
       "inputStage" : { 
        "stage" : "IXSCAN", 
        "nReturned" : 1, 
        "executionTimeMillisEstimate" : 0, 
        "works" : 2, 
        "advanced" : 1, 
        "needTime" : 0, 
        "needYield" : 0, 
        "saveState" : 0, 
        "restoreState" : 0, 
        "isEOF" : 1, 
        "invalidates" : 0, 
        "keyPattern" : { 
         "_fts" : "text", 
         "_ftsx" : 1 
        }, 
        "indexName" : "RequestId_text", 
        "isMultiKey" : true, 
        "isUnique" : false, 
        "isSparse" : false, 
        "isPartial" : false, 
        "indexVersion" : 2, 
        "direction" : "backward", 
        "indexBounds" : { 

        }, 
        "keysExamined" : 1, 
        "seeks" : 1, 
        "dupsTested" : 1, 
        "dupsDropped" : 0, 
        "seenInvalidated" : 0 
       } 
      } 
     } 
    } 
}, 

但为什么蒙戈不使用默认情况下,指数,所以我用暗示来强制索引查询下面:

db.getCollection(“RecordInfo”)。find({“RequestId”:“4513456313212313212aaaa”}).hint(“RequestId_text”)。explain(“executionStats”),它给我这些,这不是很好:

"executionStats" : { 
    "executionSuccess" : true, 
    "nReturned" : 1, 
    "executionTimeMillis" : 93, 
    "totalKeysExamined" : 49378, 
    "totalDocsExamined" : 9998, 
    "executionStages" : { 
     "stage" : "FETCH", 
     "filter" : { 
      "RequestId" : { 
       "$eq" : "4513456313212313212aaaa" 
      } 
     }, 
     "nReturned" : 1, 
     "executionTimeMillisEstimate" : 91, 
     "works" : 49379, 
     "advanced" : 1, 
     "needTime" : 49377, 
     "needYield" : 0, 
     "saveState" : 386, 
     "restoreState" : 386, 
     "isEOF" : 1, 
     "invalidates" : 0, 
     "docsExamined" : 9998, 
     "alreadyHasObj" : 0, 
     "inputStage" : { 
      "stage" : "IXSCAN", 
      "nReturned" : 9998, 
      "executionTimeMillisEstimate" : 50, 
      "works" : 49379, 
      "advanced" : 9998, 
      "needTime" : 39380, 
      "needYield" : 0, 
      "saveState" : 386, 
      "restoreState" : 386, 
      "isEOF" : 1, 
      "invalidates" : 0, 
      "keyPattern" : { 
       "_fts" : "text", 
       "_ftsx" : 1 
      }, 
      "indexName" : "RequestId_text", 
      "isMultiKey" : true, 
      "isUnique" : false, 
      "isSparse" : false, 
      "isPartial" : false, 
      "indexVersion" : 2, 
      "direction" : "forward", 
      "indexBounds" : { 
       "_fts" : [ 
        "[MinKey, MaxKey]" 
       ], 
       "_ftsx" : [ 
        "[MinKey, MaxKey]" 
       ] 
      }, 
      "keysExamined" : 49378, 
      "seeks" : 1, 
      "dupsTested" : 49378, 
      "dupsDropped" : 39380, 
      "seenInvalidated" : 0 
     } 
    } 
}, 

要summaize,我想用指数或任何方法来查询请求ID字段,它是字符串列快。但如果我强迫使用索引,它似乎不适用于我,只会让我的查询变得更糟。但如果我以另一种方式使用索引,如下所示,我可以看到一个相当不错的查询。但我不能在这个字段上指定我想用这种方式查询。 。

db.getCollection( “RecordInfo”)找到({$文字:{$搜索: “4513456313212313212aaaa”}})。解释( “executionStats”)

+0

全文搜索索引与“正常”索引非常不同。你需要知道何时使用哪个,Mongo不能仅仅为你做出决定。例如,全文索引只能找到完整的令牌,并且不能告诉你它在哪个列中找到它们。 – Thilo

+0

这不是“文本”索引。你想要一个普通的b-tree索引。只需'db.getCollection(“RecordInfo”)。createIndex({“RequestId”:1})'然后执行标准查询。 –

+0

@Thilo我们主要查询文档的字符串字段上的子字符串,这是正则表达式匹配,我应该使用什么样的索引?我猜这是坏的设计,有非常大的文件,这使得我从创建文本索引,因为很多期限列表大小限制违规? – Long

回答

0

文本搜索只能使用$text查询运算符。

当您执行db.getCollection("RecordInfo").find({"RequestId":"4513456313212313212aaaa"})时,您正在查询该字段的完全匹配。

从这个问题,看来你正在寻找的是一个常规的索引,它可以创建使用db.getCollection("RecordInfo").createIndex({"RequestId": 1})

这将使使用$text失败(因为没有文字索引),但会使你的查询常规的使用索引并避免COLLSCAN

+0

谢谢Kewne,但是我不能创建一个正常的索引,因为文档大小限制违规,errmsg:key太大而无法索引。另外我想我最好使用文本索引,因为:1,它是一个字符串字段,2,我们不搜索整个字段,我们搜索该字段的子字符串,这是一个正则表达式匹配。我对吗 ? 如果是这样,我仍然不能创建文本索引,因为字段大小限制违规,所以也许mongodb不是用来存储大文件? 在此先感谢。 – Long

+0

事情是文本搜索可能无法做到你所期望的,因为词干和其他东西(搜索'驱动器'将匹配'驾驶'和'驱动程序')。 “RequestId”字段的实际大小/格式是什么?我正在考虑的方式是用一个转换(如截断或哈希)复制该字段,使其变得更小和可索引。 – kewne

+0

Hi Kewne,RequestId字段包含如下字符串: {“Status”:{“IsSuccess”:false,“ResponseMessage”:“请求头信息错误,不能为空”,“ResponseCode”:“0020”,“WarningMessage “:null}} 有一件事我不明白,文档大小不应该超过4MB,但我会收到:”errmsg“:”尝试索引文本,其中术语列表太大,max是4mb。无论如何呢? – Long