V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
linkbg
V2EX  ›  MongoDB

MongoDB 创建复合索引的问题

  •  
  •   linkbg · 2017-05-15 23:41:27 +08:00 · 3154 次点击
    这是一个创建于 2741 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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'})
    

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

    9 条回复    2017-05-16 23:56:54 +08:00
    TJT
        1
    TJT  
       2017-05-16 00:15:38 +08:00   ❤️ 1
    顺序无关,mongo 会自己决定如何使用索引。
    另外如果你两个字段都有索引,有些情况下会有限使用单独的索引而不是联合索引,explain 一下就知道,前几天刚踩过坑。
    linkbg
        2
    linkbg  
    OP
       2017-05-16 00:29:11 +08:00
    @TJT 谢谢,那第一个那种,如果我把 b_text 索引删掉,创建复合索引的话,会不会影响只搜索 b 这个字段的效率呢?
    TJT
        3
    TJT  
       2017-05-16 00:45:10 +08:00
    @linkbg 这就不知道了,你可以实验一下:db.tests.find(QUERY).explain(),看一下 winningPlan 是什么。我觉得复合索引不会对单字段的搜索有帮助。
    TJT
        4
    TJT  
       2017-05-16 00:52:48 +08:00
    至于第一个问题,a 和 n 如果能把结果集限制的足够小,仅针对 a 和 n 创建符合索引就好,速度上不会比三个字段的符合索引慢太多。
    linkbg
        5
    linkbg  
    OP
       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
        6
    TJT  
       2017-05-16 21:28:40 +08:00
    @linkbg 怎么 query 的?数据量有多大?
    linkbg
        7
    linkbg  
    OP
       2017-05-16 22:28:18 +08:00
    @TJT db.tests.find({'n':'hk','a':'34',$text:{$search:'er'}}) ,数据量在十万级别。
    TJT
        8
    TJT  
       2017-05-16 23:35:42 +08:00
    @linkbg 看起来没问题,也没搜到有相关的问题。你试一下重建索引,如果还是不行建议去发 issue,附上重现方法和测试数据。
    linkbg
        9
    linkbg  
    OP
       2017-05-16 23:56:54 +08:00
    @TJT 好的,谢谢啦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1470 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 17:32 · PVG 01:32 · LAX 09:32 · JFK 12:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.