【问题标题】:How should I index this schema in Elasticsearch我应该如何在 Elasticsearch 中索引这个模式
【发布时间】:2014-08-26 14:07:51
【问题描述】:

我对如何在 Elasticsearch 中索引这些文档有点迷茫。

文档 1

{
    text: ['chicken']
}

文档 2

{
    text: ['chicken'], [['broth', 'stock']]
}

我需要能够使用“鸡味高汤”或“鸡味肉汤”来查询这些,并且它应该返回具有相同分数的两个文档,因为它们的所有术语都已在输入查询中匹配。 它也不应该返回只有“鸡”作为查询的 doc 2。

基本上,我想知道 'text' 字段中的所有术语都已在查询中的某处找到,并且内部数组(即:'broth' 和 'stock' 就像 OR 子句一样)。

这可能吗?

更新:

我确实找到了一种(繁琐的)方法。我通过将它们的字段组合成短语来保存文档(例如:['chicken stock', 'chicken stock'] for doc 2)。然后我使用输入的每个组合作为短语进行搜索(例如:['chicken', 'chicken flavored', 'chicken flavored balloon', 'chicken balloon', ...]。)

这个解决方案确实给了我想要的结果,但我不禁觉得这是一个可以更优雅地处理的常见情况。感觉就像 ngrams 沿着通往我答案的道路前进,但我无法完全解决。

【问题讨论】:

    标签: indexing lucene elasticsearch data-modeling


    【解决方案1】:

    当您索引文档而不添加自定义映射时,Elasticsearch 默认使用Standard analyzer

    您可以从文本字段中删除数组并将您的文档索引为:

    文档 1

    {
       "text": "chicken"
    }
    

    文档 2

    {
       "text": "chicken broth stock"
    }
    

    标准分析器将在 Lucene 索引中创建以下标记:

    文档 1

    "chicken"
    

    文档 2

    "chicken", "broth", "stock"
    

    您的文档与搜索词匹配如下:

    chicken :“chicken”一词在两个文档中都匹配,因为文档 1 中的文本字段较短,因此得分高于文档 2。

    chicken flavored:“chicken”一词在两个文档中都匹配,但没有与“flavored”一词匹配。同样,由于文档 1 中的文本字段较短,因此其得分高于文档 2。

    chicken flavored balloon:“chicken”一词在两个文档中都匹配,“broth”一词在文档 2 中也匹配。文件。文档 2 的得分高于文档 1,因为它匹配查询中的两个术语。

    我没有真正看到 ngrams 的用例,因为上面可以满足您的需求。

    【讨论】:

    • 这仍然不能完全回答他的问题。虽然你说的很准确。
    • 是的,问题在于它还会返回带有“鸡”作为唯一输入的文档 2。我会将此添加到我的规范中。
    【解决方案2】:

    所以这里有一些你可以尝试的东西。 Percolator 可以解决您的问题,但您必须改变索引文档的方式。

    所以不要像你正在做的那样索引 doc1,而是像这样索引它:

    PUT /test-index/.percolator/1
    {
        "query": {
            "term": {
               "text": {
                  "value": "chicken"
               }
            }
        }
    }
    

    而且,像这样索引 doc2:

    PUT /test-index/.percolator/2
    {
       "query": {
          "bool": {
             "must": [
                {
                   "term": {
                      "text": {
                         "value": "chicken"
                      }
                   }
                },
                {
                   "bool": {
                      "should": [
                         {
                            "term": {
                               "text": {
                                  "value": "broth"
                               }
                            }
                         },
                         {
                            "term": {
                               "text": {
                                  "value": "stock"
                               }
                            }
                         }
                      ]
                   }
                }
             ]
          }
       }
    }
    

    不,而不是查询您之前查询文档的方式,过滤它们:

    GET /test-index/all_terms_search/_percolate
    {
        "doc": {
            "text": "chicken flavored stock"
        }
    }
    

    这将获取您的两个文件。这也使您可以灵活地控制要匹配的内容和数量。当您在 percolator 中为文档的反向查询编制索引时,您为该查询提供一个 ID 并对应于该 ID,您可以以更简单的形式维护文本,以便您在 Elasticsearch 中的单独索引或其他索引中使用可以非常快速地获取匹配文档的数据存储。

    【讨论】:

    • 这实际上可以做我想要的(并且在灵活性方面更多)。虽然我不完全确定存储了几千个过滤器查询的性能。
    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2016-01-01
    • 2012-07-28
    相关资源
    最近更新 更多