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

mongodb 建立什么索引查询更快

  •  
  •   Ewig · 2018-10-30 02:14:51 +08:00 · 4652 次点击
    这是一个创建于 2228 天前的主题,其中的信息可能已经有所发展或是发生改变。
    { "_id" : ObjectId("5bc4306ec3474d78e3780213"), "name" : "日本通货交换业协会-虚拟货币交易现状报告(日文)-2018.4.10-40 页.pdf", "unique_charcter" : "FiFhAChi7LSJxIq6IGdEjgHhiLPK" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780214"), "name" : "秋叶大叔-给你一个社群你怎么管 v2-42 页.pdf", "unique_charcter" : "lnQuwPAAWDexZKnV1XbBjDRDNA71" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780215"), "name" : "清科-清科观察:存托凭证本土化获官方认可,独家解读海外中企 CDR 模式回归 A 股路径-2018.4-13 页.pdf", "unique_charcter" : "FkWuGa1VKwZj9o4w06-2hiX-GCQL" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780216"), "name" : "艾瑞-2018 年中国睡前音频收听场景研究报告-2018.3-38 页.pdf", "unique_charcter" : "FtU78sk1Emm50IRs89mQYYvc67lX" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780217"), "name" : "德勤-2018 年全球生命科学发展趋势(英文)-2018-41 页.pdf", "unique_charcter" : "FjrR7vLkB6fjOONFB04hGq1pqsmm" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780218"), "name" : "艾瑞-2018 年中国财经新媒体行业洞察报告-2018.3-48 页.pdf", "unique_charcter" : "FlXpGnt8-dTi6D5JQm9S0UsdSRYL" }
    { "_id" : ObjectId("5bc4306ec3474d78e3780219"), "name" : "艾瑞-2018 年中国共享充电宝行业研究报告-2018.3-44 页.pdf", "unique_charcter" : "Fiiab691SQI3U8LRNNP1nWPdeiCC" }

    现在我是 name 和 unique_charcter 共同建立的键 如何使 find 查询更快?
    self.xiaoMiQuanCollection.ensureIndex(key_word)
    这样就可以吗?
    13 条回复    2018-10-31 16:53:23 +08:00
    Trim21
        1
    Trim21  
       2018-10-30 02:36:26 +08:00 via Android
    不知道你一般的查询条件是什么?
    但是复合索引是同时通过 name 和 unique_charcter 查询才会通过索引,如果进行单键查询的话是不走索引的。
    yuikns
        2
    yuikns  
       2018-10-30 05:51:04 +08:00
    想要确认是否的问题。可以使用 explain

    db. xiaoMiQuanCollection.find({your_query_here}).explain()


    这个会告诉你它 hit 了哪些 index

    具体到此处,使用什么 index 作为 index value? 默认 1,长字符串可以考虑 hashed,要是保证是多字段一起查询,那么可以

    db.xiaoMiQuanCollection.ensureIndex({name:'hashed', unique_charcter: 'hashed'})
    Ewig
        3
    Ewig  
    OP
       2018-10-30 11:15:02 +08:00
    @yuikns mongodb 索引怎么还有唯一的区别,我的理解索引应该都是唯一的,否则还用索引干嘛?
    Ewig
        4
    Ewig  
    OP
       2018-10-30 11:19:10 +08:00
    @yuikns TypeError: 'Collection' object is not callable. If you meant to call the 'createIndex' method on a 'Collection' object it is failing because no such method exists.

    报错如上面的这是为啥,这是我写的创建索引的,我写 ensureindex 和 createIndex 都没有这个方法
    index = self.xiaoMiQuanCollection.createIndex({"unique_charcter": 1, "name": 'hashed'}, {"unique": True})
    res = self.xiaoMiQuanCollection.find(index)
    yuikns
        5
    yuikns  
       2018-10-30 11:35:06 +08:00
    @Ewig huh? index and constraint are different concepts.

    self 是啥? 为啥 create index 的结果会作为 query? 你是不是对 index 有什么误解啊

    mongo 花费额外的开销和约束管理另外一套数据,内容是从 value 到 key set 的一个 dict。你 db.collection_name.getIndexes() 可以看到这个列表。所谓 unique, sparse 都是对那套数据结构的 constraints

    你只要执行一次 build index 它就会永远保持,直到你显式删掉这个 index。
    因此你


    db.xiaoMiQuanCollection.createIndex({name:'hashed', unique_charcter: 'hashed'}, {unique: true})

    一次后,就不用管它了。

    然后直接 query 即可。

    你这个错误是 pymongo 里面的,好好查文档嘛: https://api.mongodb.com/python/2.8/api/pymongo/collection.html?highlight=insert#pymongo.collection.Collection.create_index

    >>> xiaoMiQuanCollection.create_index([("unique_charcter", pymongo.DESCENDING),
    ... ("name", pymongo.HASHED)], unique=True)

    显然是这样嘛
    yuikns
        6
    yuikns  
       2018-10-30 11:38:03 +08:00
    db.collection_name 是 mongo query, 不要和 python 的 api 混淆
    Ewig
        7
    Ewig  
    OP
       2018-10-30 11:54:06 +08:00
    @yuikns xiaoMiQuanCollection.create_index([("unique_charcter", pymongo.DESCENDING),
    ... ("name", pymongo.HASHED)], unique=True)

    你这个创建看,还有查找这个索引吧

    index=xiaoMiQuanCollection.create_index([("unique_charcter", pymongo.DESCENDING),
    ... ("name", pymongo.HASHED)], unique=True)
    然后查找 self.xiaoMiQuanCollection.find(index) 这样写?
    Ewig
        8
    Ewig  
    OP
       2018-10-30 11:57:03 +08:00
    我在 python 里面 query 那个 index 方法没错吧
    Ewig
        10
    Ewig  
    OP
       2018-10-30 12:16:38 +08:00
    @yuikns index = self.xiaoMiQuanCollection.create_index([("unique_charcter", pymongo.DESCENDING), ("name", pymongo.HASHED)], unique=True)
    res = self.xiaoMiQuanCollection.find(index)

    我现在这样写,报错如下

    pymongo.errors.OperationFailure: Currently only single field hashed index supported
    JCZ2MkKb5S8ZX9pq
        11
    JCZ2MkKb5S8ZX9pq  
       2018-10-30 17:08:09 +08:00
    建索引和管理之类的我都是直接 GUI 里搞定的,一次性工作,用的 NoSQLBooster。
    pymongo 就别折腾这些了,就做做查改删。
    查询条件复杂特殊固定的话用复合的索引,但一般把用到的几个键单独索引也就够了。
    Ewig
        12
    Ewig  
    OP
       2018-10-30 19:02:07 +08:00
    @JCZ2MkKb5S8ZX9pq
    index = self.xiaomiquan_collection.create_index(
    [("unique_charcter", pymongo.DESCENDING), ("name", 1)], unique=True)
    res = self.xiaomiquan_collection.find(index)

    我这个语法有问题吗?总是报错
    JCZ2MkKb5S8ZX9pq
        13
    JCZ2MkKb5S8ZX9pq  
       2018-10-31 16:53:23 +08:00
    我觉得没有必要。
    createIndex 做一次就够了,之后新录入 mongo 的数据,mongo 会自动索引,没必要每次都搞一下,做一次就永久有效,除非手动 drop。

    我没有用 pymongo 这么做过,我不知道这儿 index 返回的是什么。
    find 接受的是字典,你把 index 打出来看看是啥?不会是{name:1}吧?

    最简单你建个 test collection,随便放个十万条 name 记录,先不做 index,搜索或者排序个一万次看看时间。
    然后你 createIndex({name:1}),然后再对 name 搜索或排序一万次看看时间,还有 cpu 开销,就能感觉到差异了。

    另外查看当前 index 的命令是 getIndexes,你那个 res 是不是想查看这个?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1023 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:36 · PVG 04:36 · LAX 12:36 · JFK 15:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.