【问题标题】:How to boost documents matching one of the query_string如何提升与 query_string 之一匹配的文档
【发布时间】:2021-11-02 18:28:51
【问题描述】:

这里是 Elasticsearch 新手。我正在尝试查找名称中包含 foo 的文档,但希望优先考虑包含 bar 的文档,即具有 bar 的文档将位于列表顶部。结果没有顶部带有 bar 的结果。 boost 这里似乎没有任何效果,可能我不明白 boost 在这里是如何工作的。在这里感谢任何帮助。

query: {
    bool: {
        should: [
            {
                query_string: {
                    query: `name:foo*bar*`,
                    boost: 5
                }
            },
            {
                query_string: {
                    query: `name:*foo*`,
                }
            }
        ]
    }
}

示例文档结构:

{
    "name": "foos, one two three",
    "type": "car",
    "age": 10 
}
{
    "name": "foos, one two bar three",
    "type": "train",
    "age": 30 
}

索引映射

{
    "detail": {
        "mappings": {
            "properties": {
                "category": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "servings": {
                    "properties": {
                        "name": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

【问题讨论】:

  • 可以添加示例文档吗
  • 嗨 Jaspreet - 我添加了示例文档结构。它不是一个真实的文件。这些太大而无法包含,但示例捕获了我感兴趣的字段,并且它是文档中的顶级字段。

标签: elasticsearch elasticsearch-query


【解决方案1】:

搜索关键字字段。

如果您只运行查询的第一部分(“query”:“name:foo*bar*”),您将看到它没有返回任何内容。它正在搜索生成的令牌而不是整个字符串。 文本 "foos, one two bar three" 生成类似 ["foos","one","two","bar","three"] 的标记,查询在单个标记中搜索 "foo*bar*" 因此没有结果.关键字字段按原样存储,因此针对整个文本进行搜索。

{
  "query": {
    "bool": {
        "should": [
            {
                "query_string": {
                    "query": "name.keyword:foo*bar*",
                    "boost": 5
                }
            },
            {
                "query_string": {
                    "query": "name.keyword:*foo*"
                }
            }
        ]
    }
} 

通配符占用大量内存并且不能很好地扩展。所以最好避免它。如果 foo 和 bar 出现在 word 开头,可以使用前缀查询

{
  "query": {
    "bool": {
      "should": [
        {
          "prefix": {
            "name": "foo"
          }
        },
        {
          "prefix": {
            "name": "bar"
          }
        }
      ]
    }
  }
}

你也可以探索 ngrams

【讨论】:

  • 谢谢贾斯普雷特。包含关键字限定符后,查询不会返回任何结果。
  • 你能添加你的映射吗
  • 为问题添加了映射。
  • @broun 我检查了您的映射和示例文档,我得到了想要的结果。您可以为名称添加实际值吗
  • 以下是名称示例:“汽车,酒吧,黄色,带油漆(虚拟)”,“火车,干,蓝色,旧”
【解决方案2】:

尝试像这样切换查询的顺序:

query: {
    bool: {
        should: [
            {
                query_string: {
                    query: `name:*foo*`,
                }
            },
            {
                query_string: {
                    query: `name:foo*bar*`,
                    boost: 5
                }
            }
        ]
    }
}

它应该可以工作,但如果没有,您可能需要进行嵌套搜索。

【讨论】:

  • 这没有效果,不过还是谢谢。名称是文档中的顶级字段,为什么需要嵌套查询?
猜你喜欢
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多