MongoDB如何索引数组?
Posted
技术标签:
【中文标题】MongoDB如何索引数组?【英文标题】:How does MongoDB index arrays? 【发布时间】:2011-05-02 19:52:30 【问题描述】:在 MongoDB 中,如果我要在字段 "color"
中存储一个数组(例如 ["red", "blue"]
),它会索引 "red"
和 "blue"
,以便我可以查询 "red"
,例如,还是是否将"red", "blue"
设为复合索引?
【问题讨论】:
【参考方案1】:在索引数组时,MongoDB 会索引数组的每个值,以便您可以查询单个项目,例如“红色”。例如:
> db.col1.save('colors': ['red','blue'])
> db.col1.ensureIndex('colors':1)
> db.col1.find('colors': 'red')
"_id" : ObjectId("4ccc78f97cf9bdc2a2e54ee9"), "colors" : [ "red", "blue" ]
> db.col1.find('colors': 'blue')
"_id" : ObjectId("4ccc78f97cf9bdc2a2e54ee9"), "colors" : [ "red", "blue" ]
有关更多信息,请查看 MongoDB 关于 Multikeys 的文档:http://www.mongodb.org/display/DOCS/Multikeys
【讨论】:
是否可以搜索部分数组,例如 ("colors" : [ "red", "blue" , "green"]),我可以搜索 ("colors" : [ "red", "blue" ]) 还是我必须单独做? @GauravAbbi - 我认为这可行,但 mongo 只会使用索引来查找第一个数组键。之后,它会扫描该组文档以查找与其余键匹配的文档。 将多键索引与复合索引相对应的注意事项。例如描述主要颜色和次要颜色的索引? @GauravAbbi :我认为你应该做一个“颜色”:$in:["red", "blue"]。【参考方案2】:您可以通过在查询中附加“解释”来简单地测试索引使用情况:
> db.col1.save('colors': ['red','blue'])
# without index
> db.col1.find('colors': 'red').explain()
"queryPlanner" :
"plannerVersion" : 1,
"namespace" : "protrain.col1",
"indexFilterSet" : false,
"parsedQuery" :
"colors" :
"$eq" : "red"
,
"winningPlan" :
"stage" : "COLLSCAN", <--- simple column scan
"filter" :
"colors" :
"$eq" : "red"
,
"direction" : "forward"
,
"rejectedPlans" : [ ]
,
"serverInfo" :
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
,
"ok" : 1
# query with index
> db.col1.createIndex( "colors":1 )
> db.col1.find('colors': 'red').explain()
"queryPlanner" :
"plannerVersion" : 1,
"namespace" : "protrain.col1",
"indexFilterSet" : false,
"parsedQuery" :
"colors" :
"$eq" : "red"
,
"winningPlan" :
"stage" : "FETCH",
"inputStage" :
"stage" : "IXSCAN", <!---- INDEX HAS BEEN USED
"keyPattern" :
"colors" : 1
,
"indexName" : "colors_1",
"isMultiKey" : true,
"multiKeyPaths" :
"colors" : [
"colors"
]
,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" :
"colors" : [
"[\"red\", \"red\"]"
]
,
"rejectedPlans" : [ ]
,
"serverInfo" :
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
,
"ok" : 1
对于具有结构化索引的结构,您可以使用数组位置来索引数组内的字段:
'_id': 'BB167E2D61909E848EBC96C7B33251AC',
'hist':
'map':
'10': 1
,
'wayPoints': [
'bhf_name': 'Zinsgutstr.(Berlin)',
'ext_no': 900180542,
'lat': 52.435158,
'lon': 13.559086,
'puic': 86,
'time':
'dateTime': '2018-01-10T09: 38: 00',
'offset':
'totalSeconds': 3600
,
'train_name': 'Bus162'
,
'bhf_name': 'SAdlershof(Berlin)',
'ext_no': 900193002,
'lat': 52.435104,
'lon': 13.54055,
'puic': 86,
'time':
'dateTime': '2018-01-10T09: 44: 00',
'offset':
'totalSeconds': 3600
,
'train_name': 'Bus162'
]
db.col.createIndex( "wayPoints.0.ext_no":1 )
db.col.createIndex( "wayPoints.0.train_name":1 )
db.col.createIndex( "wayPoints.1.ext_no":1 )
db.col.createIndex( "wayPoints.1.train_name":1 )
> db.col.find(
...
... "wayPoints.ext_no": 900180542
...
... ,
...
... "wayPoints.ext_no":1,
... "wayPoints.train_name":1,
... "wayPoints.time":1
...
... ).explain()
"queryPlanner" :
"plannerVersion" : 1,
"namespace" : "db.col",
"indexFilterSet" : false,
"parsedQuery" :
"wayPoints.ext_no" :
"$eq" : 900180542
,
"winningPlan" :
"stage" : "PROJECTION",
"transformBy" :
"wayPoints.ext_no" : 1,
"wayPoints.train_name" : 1,
"wayPoints.time" : 1
,
"inputStage" :
"stage" : "FETCH",
"inputStage" :
"stage" : "IXSCAN",
"keyPattern" :
"wayPoints.ext_no" : 1
,
"indexName" : "wayPoints.ext_no_1",
"isMultiKey" : true,
"multiKeyPaths" :
"wayPoints.ext_no" : [
"wayPoints"
]
,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" :
"wayPoints.ext_no" : [
"[900180542.0, 900180542.0]"
]
,
"rejectedPlans" : [ ]
,
"serverInfo" :
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
,
"ok" : 1
【讨论】:
以上是关于MongoDB如何索引数组?的主要内容,如果未能解决你的问题,请参考以下文章