Elasticsearch嵌套数据搜索性能

时间:2019-12-01 23:06:28

标签: elasticsearch

我有以下问题: 我将书籍存储在弹性数据库中。 将每个单词存储为单独的条目很重要,因为它包含我需要的某些元数据。书籍属于类别,书籍可以属于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
  ] 
}

在上面的示例中,如果我将一本书从1个类别移到另一个类别,则只需要更新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还是很陌生,但我仍然没有数据集可以尝试使用,其中哪些解决方案似乎更有可能起作用,或者还有其他我没有想到的解决方案?

1 个答案:

答案 0 :(得分:0)

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

指数:书籍和单词

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"
            }
          }
        }
      ]
    }
  }
}

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