V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
beryl
V2EX  ›  程序员

ES 关于 doc id 查询方式的认识误区?

  •  
  •   beryl · 2020-03-25 12:35:56 +08:00 · 3476 次点击
    这是一个创建于 1705 天前的主题,其中的信息可能已经有所发展或是发生改变。

    先说明:是讨论和请教,不是分享

    最近项目中在使用 ES 做存储和查询, 以 Mysql 的思维文档 Id, 是自己自定义的( userId+type )。认为这种方式查询:

    twitter/tweet/0
    

    但是查各种资料,并没有验证直接使用 id 这种是高效的, 也可以使用 DSL query 查询:

    匹配 userId + type

    所以想问下: get api 和 DSL query 差异在哪里呢, 自定义 id 并直接查询是不是更高效呢

    第 1 条附言  ·  2020-03-25 14:32:30 +08:00
    抱歉,可能是没描述清楚

    核心疑惑是:使用 doc Id 直接查询是不是更快
    13 条回复    2020-03-26 01:24:25 +08:00
    RedisMasterNode
        1
    RedisMasterNode  
       2020-03-25 13:12:52 +08:00
    GET API 是根据 ID 获取的过程,这个过程中你的目标是明确(且唯一的),包括需要在哪个分片进行获取

    Query 的时候,根据你的条件(例如查询 id 为 xxx 的 doc ),在各个分片中进行“搜索”,获取各个分片符合条件的 doc 的 id,在协调节点中进行合并,合并结果回到分片中拿出完整数据( query then fetch,如果是 query and fetch 等会略有不同)
    beryl
        2
    beryl  
    OP
       2020-03-25 13:34:06 +08:00
    所以还是 get api 根据 id 直接获取更快对么
    wph95
        3
    wph95  
       2020-03-25 13:49:13 +08:00
    有点没看懂 强答一下,众所周知 elasticsearch 是 基于 lucene 上面包了一层

    lucene document 被写入的时候会分配一个 seq id,也被称作是 doc id 。直接用这个 id 肯定是最高效的 勉强可以等价 mysql 里的 id

    elasticsearch 的 document 是在 lucene 的 document 上加了东西。印象里 elasticsearch 会把 uid 转成 lucene docID (记得 lucene 的 docid 不能自定义 es 的可以)

    至于 get api 和 DSL query,看过 es 的 6.3 的 dsl 代码, uid 是个特殊的字段的。所以讲道理 get api 和 DSL query 是等价的,get api 是一个 dsl query 的 template,不应该会有明显的性能差距。
    gimp
        4
    gimp  
       2020-03-25 14:07:54 +08:00
    复杂查询时使用 GET 参数方式可读性较差,理论上,相同功能的查询,它们两个性能是等价的。
    wangyzj
        5
    wangyzj  
       2020-03-25 14:21:56 +08:00
    不太懂楼主啥意思
    beryl
        6
    beryl  
    OP
       2020-03-25 14:33:21 +08:00
    @wangyzj
    抱歉没描述清楚,已补充
    核心疑惑是:使用 doc Id 直接查询是不是更快
    misaka19000
        7
    misaka19000  
       2020-03-25 14:37:54 +08:00
    性能肯定不一样啊,一个直接取数据,一个多了 query 这个过程
    wangyzj
        8
    wangyzj  
       2020-03-25 15:29:46 +08:00
    @beryl 没做过测试
    我认为应该直接 get 应该更快吧
    xiaozi
        9
    xiaozi  
       2020-03-25 15:36:51 +08:00
    query 是准实时,get 是实时
    beryl
        10
    beryl  
    OP
       2020-03-25 15:54:26 +08:00
    @xiaozi 怎么理解
    xiaozi
        11
    xiaozi  
       2020-03-25 16:01:38 +08:00
    @beryl

    对于 Search 类请求,查询的时候是一起查询内存和磁盘上的 Segment,最后将结果合并后返回。这种查询是近实时( Near Real Time )的,主要是由于内存中的 Index 数据需要一段时间后才会刷新为 Segment 。

    对于 Get 类请求,查询的时候是先查询内存中的 TransLog,如果找到就立即返回,如果没找到再查询磁盘上的 TransLog,如果还没有则再去查询磁盘上的 Segment 。这种查询是实时( Real Time )的。这种查询顺序可以保证查询到的 Doc 是最新版本的 Doc,这个功能也是为了保证 NoSQL 场景下的实时性要求。
    w0000
        12
    w0000  
       2020-03-25 16:04:47 +08:00
    强行答一波,两个查询肯定是有差异的,说到底导致查询的性能差异还是要看查询是怎么走的索引,query 的话,如果你的 ID 是当 text 类型,那么走倒排索引,如果 ID 是 keyword 类型,走的是列式存储,而 get 走的是正向索引,总体来说,keyword 类型和 ID 的查询速度是差不多的
    123444a
        13
    123444a  
       2020-03-26 01:24:25 +08:00 via Android
    性能差别比 HBASE 的 get 和 scan 的差别要小
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3044 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:51 · PVG 21:51 · LAX 05:51 · JFK 08:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.