【问题标题】:Elasticsearch nested data search performanceElasticsearch 嵌套数据搜索性能
【发布时间】:2019-12-01 23:06:28
【问题描述】:

我有以下问题: 我将书籍存储在弹性数据库中。 将每个单词存储为单独的条目很重要,因为它包含我需要的某些元数据。书籍属于类别,书籍可以属于1个或多个类别,并且是可变属性(书籍-类别关系也保存在MySQL中)。预计书籍数量为数千本。我需要通过一个单词快速搜索所有书籍(例如,有人搜索单词“test”,我需要获取包含该单词以及在哪些页面中的书籍。)。也可以按类别限制搜索。

我的困境是,我是否应该将一本书的单词保存在嵌套字段中,例如

{
 "book_name": "book1",
 "book_categories": ["cat1", "cat2", ...],
 "book_words": [
   {
     "some_word_meta": "...",
     "page": 1
     "word_value": "word1"
   },
   {
     "some_word_meta": "...",
     "page": 1
     "word_value": "word2"
   } ... lots of these
 ]
},
{
 "book_name": "book2",
 "book_categories": ["cat5", "cat6"],
 "book_words": [
    {
    "some_word_meta": "...",
    "page": 1,
    "word_value": "wordx"
    }, ... lots of these
  ] 
}

在上面的例子中,如果我将一本书从一个类别移动到另一个类别,我只需要在 elastic 中更新 1 条记录。 这种嵌套会影响搜索性能吗?

我也不能在弹性中保存类别信息,并且总是在查询中传递书名(因为 MySQL 知道哪些书属于一个类别),但是我会在搜索查询中得到类似的内容: book_name in ["book1", "book2", ... thousands more] and word == 'wordx'。在这种情况下,书籍可以展平:

{
"book_name": "book1",
"page": 1,
"word_value": "word1",
"some_word_meta: "..."
},
{
"book_name": "book1",
"page": 1,
"word_value": "word2",
"some_word_meta: "..."
}

数据重复很多,每个单词都明确知道自己属于哪本书,搜索查询看起来很糟糕。

我对 elasticsearch 很陌生,但我仍然没有数据集来尝试它,这些解决方案中哪个似乎更有可能起作用,或者还有其他一些我没有想到的解决方案?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我的建议是拥有多个索引并在应用程序端执行少量操作。

    索引:书籍和文字

    Books 
    {
      "name" :
      "other_attributes"
    }
    
    Words
    [
      {
        "metadata": ...
        "word": word1,
        "categories": ["thriller"],
        "book": ["book1_page1", "book1_page2"]
      },
      {
        "metadata": ...,
        "word": word1,
        "categories": ["romance"],
        "book": ["book9_page31"]
      }
    ]
    

    当你说带上所有带有“概念”字样的书时,

    GET words/_search
    {
      "query": {
        "term": {
          "word": {
            "value": "Concepts"
          }
        }
      }
    }
    

    对于类别搜索,

    GET words/_search
    {
      "query": {
        "term": {
          "categories": {
            "value": "Thriller"
          }
        }
      }
    }
    

    要获取所有带有“concept”字样且属于“romance”类型的页码和元数据的书,

    GET words/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "FIELD": {
                  "value": "concept"
                }
              }
            },
            {
              "term": {
                "category": {
                  "value": "romance"
                }
              }
            }
          ]
        }
      }
    }
    

    注意:您还可以查询多个索引。

    【讨论】:

    • 有趣的想法,但同一个词在每本书/页面中具有不同的元数据。此外,我从不需要搜索类别,类别应该只是一个过滤器,例如find word 'concepts' in books that belong to 'Thriller', 'Horror' etc categories. 这应该返回一个单词列表及其元数据、书籍和该书中的页面。
    • 这种设计适用于这些用例。要在单个查询中获取它,您可以将类别移动到单词索引。我已经用更新的查询更新了答案
    猜你喜欢
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    相关资源
    最近更新 更多