如何在ElasticSearch中存储关系数据

jvlzgdj9  于 2023-01-08  发布在  ElasticSearch
关注(0)|答案(3)|浏览(166)

在elasticsearch中存储关系数据有哪些选项?我知道以下方法
1.嵌套对象:-我不想以嵌套格式存储数据,因为我想更新一个文档而不更改另一个文档,如果我使用嵌套对象,则父文档中的子数据将重复。
1.父子:-我不想在单个索引中存储数据,但要使用父子数据,需要在一个索引(不同类型)中存在。我知道在https://github.com/elastic/elasticsearch/issues/15613问题中提到的未来版本中将删除此限制,但我希望解决方案应与5.5版本一起工作。
除了上述方法外,还有其他方法吗?

nwo49xxi

nwo49xxi1#

    • 嵌套对象是一种完美的方法。如果正确更新子对象,父文档中的子对象将不会重复。我在我的一个用例中使用了相同的方法,我需要维护主从一对多关系的关系数据。我已经为Update API编写了一个轻松脚本Add**&Update父文档中现有的嵌套子对象,而不会创建重复或重复的条目。
    • 更新答案:**

下面是带有嵌入嵌套类型文档"child"的父子嵌套类型文档的结构。

{
    "parent_id": 1,
    "parent_name": "ABC",
    "parent_number": 123,
    "parent_addr": "123 6th St. Melbourne, FL 32904"
    "childs": [
      {
        "child_id": 1,
        "child_name": "PQR",
        "child_number": 456,
        "child_age": 10
      },
      {
        "child_id": 2,
        "child_name": "XYZ",
        "child_number": 789,
        "child_age": 12
      },
      {
        "child_id": 3,
        "child_name": "QWE",
        "child_number": 234,
        "child_age": 16
      }

    ]   
}

Map如下所示:

PUT parent/
{
  "parent": {
    "mappings": {
      "parent": {
        "properties": {
          "parent_id": {
            "type": "long"
          },
          "parent_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "parent_number": {
            "type": "long"
          },
          "parent_addr": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "child_tickets": {
            "type": "nested",
            "properties": {
              "child_id": {
                "type": "long"
              },
              "child_name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "child_number": {
                "type": "long"
              },
              "child_age": {
                "type": "long"
              }
            }
          }
        }
      }
    }
  }
}

在RDMS中,这两个实体(父实体、子实体)是两个不同的表,在父实体-〉子实体之间具有一对多关系。父实体的id是子实体行的外键。(两个表的id都必须是)
现在在Elasticsearch中,要索引父文档,我们必须有id来索引它,在本例中是parent_id。索引父文档查询(parent_id是我所说的id,并索引id(_id)= 1的文档):

POST parent/parent/1
{
    "parent_id": 1,
    "parent_name": "ABC",
    "parent_number": 123,
    "parent_addr": "123 6th St. Melbourne, FL 32904"
}

现在,将子项添加到父项。为此,您将需要子文档,该文档应具有子项ID和父项ID。要添加子项,父项ID必须为。下面是添加新子项或更新现有子项的更新查询。

POST parent/parent/1/_update
{
    "script":{
    "lang":"painless",
    "inline":"if (!ctx._source.containsKey(\"childs\")) {
                ctx._source.childs = [];
                ctx._source.childs.add(params.child);
            } else {
                int flag=0;
                for(int i=0;i<ctx._source.childs.size();i++){
                    if(ctx._source.childs[i].child_id==params.child.child_id){
                        ctx._source.childs[i]=params.child;
                        flag++;
                    }
                }
                if(flag==0){
                    ctx._source.childs.add(params.child);
                }
            }",
    "params":{
        "child":{
                "child_id": 1,
                "child_name": "PQR",
                "child_number": 456,
                "child_age": 10
            }
        }
    }
}

来吧,干杯!
如果你还需要什么就告诉我。

vof42yt1

vof42yt12#

还有两种方法:Denormalizationrunning multiple queries for joins
反规范化会占用更多的空间并增加写入时间,但您只需要运行一个查询来检索数据,因此读取时间会得到改善。由于您不想将数据存储在单个索引中,因此联接可能会帮助您解决这个问题。

xurqigkl

xurqigkl3#

有四种机制可用于提供关系数据建模支持。每种机制都有其优缺点,因此它们适用于不同的情况......下面是总结:

内部对象

  • 简单、快速、高性能
  • 仅在保持一对一关系时适用
  • 无需特殊查询
    嵌套
  • 嵌套文档存储在同一个Lucene块中,这有助于提高读取/查询性能。阅读嵌套文档比读取父/子文档要快。
  • 更新嵌套文档(父文档或嵌套子文档)中的单个字段将强制ES重新索引整个嵌套文档。这对于大型嵌套文档来说可能代价非常高
  • 无法“交叉引用”嵌套文档
  • 最适合不经常更改的数据
    父/子
  • 子对象与父对象分开存储,但是被路由到同一个shard,因此父对象/子对象在读取/查询方面的性能略低于嵌套对象
  • 父/子Map有一点额外的内存开销,因为ES在内存中维护一个“连接”列表
  • 更新子文档不会影响父文档或任何其他子文档,这可能会为大型文档保存大量索引
  • 父/子分类/评分可能很困难,因为Has
  • “子项”/“具有父项”操作有时可能不透明
    反规格化
  • 你可以自己处理所有的关系!
  • 最灵活,管理开销最大
  • 性能可能更高或更低,具体取决于您的设置

如需了解更多信息,请访问:https://www.elastic.co/blog/managing-relations-inside-elasticsearch

相关问题