Mongodb:子文档数组

时间:2016-09-04 10:14:14

标签: node.js mongodb

所以我有一个文件结构:

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

我有一个像这样的索引集:

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

任务是创建一个用于搜索这些文档的webform。表单中的字段不固定,可以添加。基本上我不知道用户想要过滤哪些字段,所以我无法设置合适的复合索引。数据库将超过20万个文档,现在大约是10密耳。

问题在于我的索引无法正常工作或出错。 看一些例子。

此查询根本没有索引。

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
}

据我所知,索引存在,但由于某种原因不起作用。

我应该如何构建我的字段或如何为此设置索引?

1 个答案:

答案 0 :(得分:0)

createIndex()将在集合上创建索引,而如果索引尚不存在,ensureIndex()会在指定字段上创建索引。 所以你的第二个查询在firstQuery失败时有效。尝试使用dropIndex()删除索引,然后使用createIndex重建索引()

检查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" : {
            ...
         }
      }
   },