MongoDB 创建复合索引的问题

2017-05-15 23:41:27 +08:00
 linkbg

MongoDB 版本:3.4

1 )这个情况下,怎么才能建立我想要的复合索引呢?

存在索引:

db.tests.createIndex({'b':'text'})
db.tests.createIndex({'n':1})
db.tests.createIndex({'a':1})

现在我想创建一个复合索引:

db.tests.createIndex({'n':1,'a':1,'b':'text'})

#Error info:
{
	"ok" : 0,
	"errmsg" : "only one text index per collection allowed, found existing text index \"b_text\"",
	"code" : 67,
	"codeName" : "CannotCreateIndex"
}

2 )在这个版本下,是不是不需要严格去规定复合查询时的条件的位置? 存在以下的复合索引

db.tests.createIndex({'n':1,'a':1})

以下的两种情况都使用到了索引:

#1
db.tests.find({'n':'shandong','a':'88'})

#2
db.tests.find({'a':'88', 'n':'shandong'})

两个问题,不是太明白,还望指点。谢谢

3069 次点击
所在节点    MongoDB
9 条回复
TJT
2017-05-16 00:15:38 +08:00
顺序无关,mongo 会自己决定如何使用索引。
另外如果你两个字段都有索引,有些情况下会有限使用单独的索引而不是联合索引,explain 一下就知道,前几天刚踩过坑。
linkbg
2017-05-16 00:29:11 +08:00
@TJT 谢谢,那第一个那种,如果我把 b_text 索引删掉,创建复合索引的话,会不会影响只搜索 b 这个字段的效率呢?
TJT
2017-05-16 00:45:10 +08:00
@linkbg 这就不知道了,你可以实验一下:db.tests.find(QUERY).explain(),看一下 winningPlan 是什么。我觉得复合索引不会对单字段的搜索有帮助。
TJT
2017-05-16 00:52:48 +08:00
至于第一个问题,a 和 n 如果能把结果集限制的足够小,仅针对 a 和 n 创建符合索引就好,速度上不会比三个字段的符合索引慢太多。
linkbg
2017-05-16 16:05:35 +08:00
@TJT 在删除 b_text 之后,我创建以一个
```
db.tests.createIndex({'n':1,'a':1,'b':'text'})

```
可是在执行查询的时候,整个 mongo 就退出了。使用不了。日志:
```
[conn1] Invariant failure amExpr->numChildren() >= prefixEnd src/mongo/db/query/planner_access.cpp 466
[conn1]

***aborting after invariant() failure


[conn1] Got signal: 6 (Aborted).

```

权限也是正常的。其他 find 正常,只要用到这个索引就 over。
TJT
2017-05-16 21:28:40 +08:00
@linkbg 怎么 query 的?数据量有多大?
linkbg
2017-05-16 22:28:18 +08:00
@TJT db.tests.find({'n':'hk','a':'34',$text:{$search:'er'}}) ,数据量在十万级别。
TJT
2017-05-16 23:35:42 +08:00
@linkbg 看起来没问题,也没搜到有相关的问题。你试一下重建索引,如果还是不行建议去发 issue,附上重现方法和测试数据。
linkbg
2017-05-16 23:56:54 +08:00
@TJT 好的,谢谢啦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/361556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX