【问题标题】:Elasticsearch index designElasticsearch 索引设计
【发布时间】:2015-04-11 17:42:37
【问题描述】:

我维护了多年的用户活动,包括浏览、购买数据。浏览/购买中的每个条目都是一个 json 对象:{item_id: id1, item_name, name1, category: c1, brand:b1, event_time: t1}。

我想编写不同的查询,例如获取在时间范围 t1 到 t2 内浏览过商品 A 和/或购买过商品 B 的所有客户。有数千万客户。

我目前的设计是为每个客户使用嵌套对象:

客户1:
       客户 ID,ID1,
       姓名:姓名1,
       国家:美国,
       浏览:[{browseentry1_json},{browseentry2_json},...],
       购买:[{purchase entry1_json},{purchase entry2_json},...]

通过这种设计,我可以轻松地用嵌套查询组合各种查询。唯一的问题是旧的浏览/购买数据很难过期:例如,我只想保留多年的浏览/购买数据。在这个设计中,我必须在某个时候,读取整个索引,删除过期的浏览/购买数据,然后将它们写回。

另一种设计是使用父/子结构。 type:user是browse and purchase类型的父级。 类型浏览将包含每个浏览条目。 尽管使用按查询删除似乎更容易删除旧数据,但对于上述查询,我​​将不得不执行多个和/或 has_child 查询,而且性能会低得多。事实上,最初我使用的是父/子结构,但查询时间似乎很长。因此我放弃了它并尝试切换到嵌套对象。

我也在考虑使用嵌套对象,但将数据分解为不同的索引(如每月索引),以便我可以轻松地使旧数据过期。这种方法的问题是我必须查询这些多个索引,并对其进行聚合以获得不同的用户,我认为这会慢得多。(还没有尝试过)。这个项目的一个要求是能够在可接受的时间范围内给出查询的计数。(如秒)我担心这种方法可能不可接受。

ES集群是7台机器,每台8核,32G内存。 有什么建议么?

提前致谢! 陈

【问题讨论】:

    标签: performance elasticsearch


    【解决方案1】:

    我不会创建客户索引,而是创建一个“浏览”索引(索引)和一个由时间跨度分隔的“购买”索引(例如:每月,正如您在上一段中提到的)。 在每个结构中,我都会添加客户字段。现在您面临两种不同的方法: 1.您可以只添加对客户的引用(例如id),然后再次查询以获取他的详细信息。 2. 如果您没有任何存储问题,您可以将所有客户的数据保存在每个结构中。

    如果这不足以提高性能,您可以将其与“路由”结合使用,并将所有特定用户的数据保存在同一个分片上。并且 Elasticsearch 不需要在分片之间获取数据(您可以观看 this video Shay Benon 解释“用户数据流”)

    尼夫

    【讨论】:

    • 这是最自然的思维方式。但是我怎样才能做一个简单的“和”查询交叉索引,比如“谁浏览了商品 A,购买了商品 B”?
    • 您可以在索引和映射之间使用逗号。顺便说一句,我错误地编写了不同的索引,但您可以将您的类型(“浏览”、“购买”)作为不同的映射。
    猜你喜欢
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    相关资源
    最近更新 更多