【问题标题】:Querying an elasticsearch index for data that isn't 1:1 with the document查询与文档不是 1:1 的数据的弹性搜索索引
【发布时间】:2020-02-01 00:45:56
【问题描述】:

如果我从标准化数据开始,例如:

Book 
|->belongs to Author
|->belongs to Genre

我在我的 ES 索引中对它进行非规范化,我可能会得到如下行的东西:

book1 author1 genre1
book2 author1 genre2
book3 author2 genre1
book4 author3 genre1

这个索引似乎会自然地回答有关book 的查询,因为每个文档与book 是1:1 的。

但是,如果我想回答有关 authorgenre 的查询而不参考 book 怎么办?假设要公开一个带有 author 列表的 UI,该列表可由 author namegenre 过滤。或者是genre 的列表,没有提到bookauthor

我可以轻松地为 authorbookgenre 分别创建一个索引,但这要么将我的索引变成我的规范化关系数据的镜像(这违背了在非规范化索引中快速搜索的目的) 或者我必须在作者更改时更新 3 个索引。

如果我选择以这种方式简化索引,我会不会在查询时给自己制造一个不可持续的问题?

聚合是我听说过的一种用于生成按某些常见字段分组的文档的东西。那是我可以在这里使用的东西吗?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    这取决于您的数据集有多复杂。如果您有大量要标准化的字段,您可以使用 Terms Lookup 并在单独的索引中分隔 AuthorBook 并使用 id 链接它们。

    但是,如果你的数据集不是太大,那么你可以像下面的例子一样简单:

    您可以搜索作者或书籍,它将返回与查询匹配的所有文档

    PUT t1
    
    POST t1/_doc/1
    {
      "book": "book1",
      "author": "author1"
    }
    
    POST t1/_doc/2
    {
      "book": "book2",
      "author": "author1"
    }
    
    POST t1/_doc/3
    {
      "book": "book3",
      "author": "author2"
    }
    
    POST t1/_doc/4
    {
      "book": "book4",
      "author": "author3"
    }
    

    QUERY 1 - 图书查找 - 返回图书 1

     POST t1/_search
        {
          "query": {
            "terms": {
              "book": [
                "book1"
              ]
            }
          }
        }
    
        #Response
        {
          "took" : 0,
          "timed_out" : false,
          "_shards" : {
            "total" : 1,
            "successful" : 1,
            "skipped" : 0,
            "failed" : 0
          },
          "hits" : {
            "total" : {
              "value" : 1,
              "relation" : "eq"
            },
            "max_score" : 1.0,
            "hits" : [
              {
                "_index" : "t1",
                "_type" : "_doc",
                "_id" : "1",
                "_score" : 1.0,
                "_source" : {
                  "book" : "book1",
                  "author" : "author1"
                }
              }
            ]
          }
        }
    

    QUERY 2 - 作者查找 - 返回 book1 和 book2

    POST t1/_search
    {
      "query": {
        "terms": {
          "author": [
            "author1"
          ]
        }
      }
    }
    
    #Author Response
    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 2,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "t1",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "book" : "book1",
              "author" : "author1"
            }
          },
          {
            "_index" : "t1",
            "_type" : "_doc",
            "_id" : "2",
            "_score" : 1.0,
            "_source" : {
              "book" : "book2",
              "author" : "author1"
            }
          }
        ]
      }
    }
    

    【讨论】:

    • 谢谢,我觉得第二个选项是正确的。如果我想使用只关心作者而不关心书籍的 UI 来管理作者怎么办?即从所有作者的列表开始,然后通过author name 和索引上可以独立于书籍理解的其他字段(author dobgenre 等)缩小范围。并且说我还想要一个仅用于管理 genre 的 UI(同样,没有书籍字段)?从单个索引处理所有这些独立查询是否很奇怪?
    猜你喜欢
    • 2015-12-18
    • 2014-06-22
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多