2016-09-04 105 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

相关问题