2016-09-04 103 views
1

所以我有一個文件的這種結構:MongoDB的:子文檔數組的索引

{ 
_id: "123abc", 
mainProps: [ 
    { 
     "countrycode": "US" 
    }, 
    { 
     "yearfounded": "2011" 
    }, 
    { 
     "city": "New York" 
    }, 
    ... 
], 
otherProps: [{}, {}, ...] 
} 

我有一個索引設置是這樣的:

db.companies.ensureIndex({mainProps: 1}) 

的任務是創建一個Web窗體中搜索這些文件。表單中的字段不是固定的,可以添加。基本上我不知道用戶想要過濾哪些字段,所以我不能設置適當的複合索引。數據庫將超過20mil文件,現在大約10mil。

問題是我的索引不起作用,或者工作不正確。 查看一些示例。

此查詢根本沒有索引。

db.companies.find({'mainProps.yearfounded': '2012'}).explain() 

此查詢使用索引,並罰款。

db.companies.find({mainProps:{'yearfounded': '2012'}}).explain() 

而且這樣的掛起(如果我刪除的解釋()),我不知道是否它執行或正在發生的事情。

db.companies.find(
    {$or: [ 
    { mainProps: {foundedyear: '2012'}}, 
    { mainProps: {foundedyear: '2011'}}, 
    ]} 
).explain() 

對於最後一個查詢解釋我得到了這樣的東西。

{ 
    "queryPlanner" : { 
      "plannerVersion" : 1, 
      "namespace" : "leadsbase.companies", 
      "indexFilterSet" : false, 
      "parsedQuery" : { 
        "$or" : [ 
          { 
            "mainProps" : { 
              "$eq" : { 
                "foundedyear" : "2012" 
              } 
            } 
          }, 
          { 
            "mainProps" : { 
              "$eq" : { 
                "foundedyear" : "2011" 
              } 
            } 
          } 
        ] 
      }, 
      "winningPlan" : { 
        "stage" : "SUBPLAN", 
        "inputStage" : { 
          "stage" : "FETCH", 
          "inputStage" : { 
            "stage" : "IXSCAN", 
            "keyPattern" : { 
              "mainProps" : 1 
            }, 
            "indexName" : "mainProps_1", 
            "isMultiKey" : true, 
            "isUnique" : false, 
            "isSparse" : false, 
            "isPartial" : false, 
            "indexVersion" : 1, 
            "direction" : "forward", 
            "indexBounds" : { 
              "mainProps" : [ 
                "[{ foundedyear: \"2011\ 
" }, { foundedyear: \"2011\" }]", 
                "[{ foundedyear: \"2012\ 
" }, { foundedyear: \"2012\" }]" 
              ] 
            } 
          } 
        } 
      }, 
      "rejectedPlans" : [ ] 
    }, 
    "serverInfo" : { 
      "host" : "vm1", 
      "port" : 27017, 
      "version" : "3.2.8", 
      "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbag0" 
    }, 
    "ok" : 1 
} 

所以據我瞭解索引是存在的,但由於某種原因不能正常工作。

我應該如何構建我的領域,或者我應該如何爲此設置索引?

+0

爲什麼你說最後一個查詢不使用索引掃描,當這個winsplan說要使用IXSCAN? – vdj4y

+0

>「據我瞭解,索引是存在的,但由於某種原因不起作用。」 我不太明白髮生了什麼事,但是如果沒有「解釋」就執行此操作需要花費很長時間,即使我將「查找」更改爲「計數」 – Tooyz

回答

0

createIndex()將在集合上創建索引,而如果索引尚不存在,ensureIndex()將在指定的字段上創建一個索引。 因此,當第一個查詢失敗時,您的第二個查詢可以工作。嘗試用dropIndex()來刪除索引,然後用createIndex()


一種方式重建索引檢查O性能的indexscan,您可以檢查 「executionStats」

db.collection.explain("executionStats").find(<your query>) 

然後從結果,檢查此兩個場:

executionSuccess.totalKeysExamined, executionSuccess.totalDocsExamined 

對於大多數情況下,如果你的指數是良好的,雙方應該有相同的號碼。或者你可以閱讀更多documentation

"executionStats" : { 
    "executionSuccess" : <boolean>, 
    "nReturned" : <int>, 
    "executionTimeMillis" : <int>, 
    "totalKeysExamined" : <int>, // this is your index keys 
    "totalDocsExamined" : <int>, // this is total docs examined 
    "executionStages" : { 
     "stage" : <STAGE1> 
     "nReturned" : <int>, 
     "executionTimeMillisEstimate" : <int>, 
     "works" : <int>, 
     "advanced" : <int>, 
     "needTime" : <int>, 
     "needYield" : <int>, 
     "isEOF" : <boolean>, 
     ... 
     "inputStage" : { 
     "stage" : <STAGE2>, 
     ... 
     "nReturned" : <int>, 
     "executionTimeMillisEstimate" : <int>, 
     "keysExamined" : <int>, 
     "docsExamined" : <int>, 
     ... 
     "inputStage" : { 
      ... 
     } 
     } 
    }, 
+0

當我做 'db.companies.find( {$或:[[ {mainProps:{createdyear:'2012'}}, {mainProps:{createdyear:'2011'}}, ]} )。解釋(「executionStats」)' 控制檯只是掛起。沒有參數,沒關係。也許我的mongo還有其他問題? – Tooyz

+0

嗨,你應該把find()之前的解釋()之前。如果你放之後,控制檯會嘗試先運行你的查詢, – vdj4y

+0

這樣工作。得到這個:[link](http://codebeautify.org/online-json-editor/cb77b1cc)。執行時間對我來說太大了(37s),爲什麼我的第二個查詢幾乎是即時的? – Tooyz

相關問題