【问题标题】:How to 'join' two indexes in ElasticSearch如何在 ElasticSearch 中“加入”两个索引
【发布时间】:2016-01-24 22:27:33
【问题描述】:

我有两个必须分开的索引:

// index = `order_item`
{
    "ID": 1,
    "Name": "Shoes",
    "Price": 9.99,
    "OrderID": 82
},{
    "ID": 1,
    "Name": "Hat",
    "Price": 19.99,
    "OrderID": 82
}

// index = `order`
{
    "ID": 82,
    "Customer": "John Smith"
}

我将如何在搜索中“加入”这两个表,以便它返回类似于以下内容的内容:

results = {
    "ID": 1,
    "Name": "Shoes",
    "Price": 9.99,
    "Order.ID": 82,
    "Customer": "John Smith"
},{
    "ID": 1,
    "Name": "Hat",
    "Price": 19.99,
    "Order.ID": 82,
    "Customer": "John Smith"
}

【问题讨论】:

  • 很遗憾,大卫做不到
  • @eliasah -- 我明白了,谢谢。那么您在这里的建议是什么,因为我们可以如何合并数据。例如,诸如合并它然后创建第三个索引的处理作业之类的东西。这里有什么可能吗?
  • 您是否考虑过文档之间的父/子关系? elastic.co/guide/en/elasticsearch/guide/current/… 请注意,单个索引与 RDBMS 中的表不同。
  • 这当然取决于数据的大小。在这种情况下,执行连接的处理作业适合创建第三个索引,就像您建议的那样听起来像是一个完美的主意。我通常在 Spark 之上使用 Elasticsearch 对大数据执行转换。
  • @eliasah 很有趣。您可以提供有关 es + Spark 的咨询工作吗?如果是这样,您是否有链接或我可以连接的某种方式。谢谢。

标签: json elasticsearch


【解决方案1】:

正如your other question 中的回答,没有什么可以阻止您在索引时将Customer 名称存储在每个order_item 文档中,同时仍然有一个专用索引orders 也包含Customer 数据。请记住,这一切都是为了巧妙地非规范化您的数据,以便您的每个文档都像您需要的那样“独立”。

curl -XPUT localhost:9200/order_items/order_item/1 -d '{
    "ID": 1,
    "Name": "Shoes",
    "Price": 9.99,
    "OrderID": 82,
    "Customer": "John Smith"
}'

curl -XPUT localhost:9200/order_items/order_item/2 -d '{
    "ID": 2,
    "Name": "Hat",
    "Price": 19.99,
    "OrderID": 82,
    "Customer": "John Smith"
}

此解决方案的优点是每个订单商品都是完全独立的,您可以在OrderID 上对它们进行分组/聚合,以获取给定订单的所有商品。

另外,正如@JohnAment 在他的评论中提到的那样,order/order_item 用例也是一个很好的选择

  1. parent/child relationship
  2. nested objects

在第一种情况下,您将拥有一个 order "parent" 文档...

curl -XPUT localhost:9200/orders/order/82 -d '{
    "ID": 82,
    "Customer": "John Smith"
}'

还有几个您使用其父 ID 索引的 order_item“子”文档:

curl -XPUT localhost:9200/order_items/order_item/1?parent=82 -d '{
     "ID": 1,
     "Name": "Shoes",
     "Price": 9.99
}'
curl -XPUT localhost:9200/order_items/order_item/2?parent=82 -d '{
     "ID": 2,
     "Name": "Hat",
     "Price": 19.99
}'

在第二种情况下,您的 order 文档将在嵌套的 OrderItems 属性中包含所有订单项,如下所示:

curl -XPUT localhost:9200/orders/order/82 -d '{
    "ID": 82,
    "Customer": "John Smith",
    "OrderItems": [
      {
        "ID": 1,
        "Name": "Shoes",
        "Price": 9.99
      },{
        "ID": 2,
        "Name": "Hat",
        "Price": 19.99
      }
    ]
}'

【讨论】:

  • 您对这种方法有什么新的更新,尤其是在 elastic 6 中映射多种类型受到影响的情况下?
  • @KalpeshSoni 父/子在 ES6 中仍然可以通过join 字段实现,尽管您现在每个索引只能有一个父/子联接。
  • 好的,当你有很多过滤和排序需求时,你更喜欢嵌套对象还是连接字段,就像 SQL where 子句和 order by 所做的那样
  • @KalpeshSoni 这真的取决于用例。随意创建一个突出您的特定需求的新问题。
  • 有一个错字。在“客户”之后使用逗号 (,):“John Smith”
猜你喜欢
  • 1970-01-01
  • 2022-11-27
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
相关资源
最近更新 更多