elasticsearch - 如何在所有字段中进行搜索并使用弹性搜索中指定的字段进行搜索?
问题描述
我对弹性搜索很陌生,我如何编写一个查询,在文档的所有字段中搜索关键字(即测试关键字),以及在特定字段中搜索的另一个关键字。
这可以使用query_string
但我们不能在指定嵌套字段的嵌套字段中进行搜索,所以我使用LUQUM将 lucene 查询转换为 Elasticsearch DSL。
以下是示例用例:
我有一个映射:
"mappings": {
"properties": {
"grocery_name":{
"type": "text"
},
"items": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"stock": {
"type": "integer"
},
"category": {
"type": "text"
}
}
}
}
}
}
数据如下所示
{
"grocery_name": "Elastic Eats",
"items": [
{
"name": "Red banana",
"stock": "12",
"category": "fruit"
},
{
"name": "Cavendish banana",
"stock": "10",
"category": "fruit"
},
{
"name": "peach",
"stock": "10",
"category": "fruit"
},
{
"name": "carrot",
"stock": "9",
"category": "vegetable"
},
{
"name": "broccoli",
"stock": "5",
"category": "vegetable"
}
]
}
我如何查询以获取所有项目名称与来自grocery_name: Elastic Eats的香蕉相匹配的项目?
尝试使用*
and _all
,它没有用。
示例查询:
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"grocery_name": {
"query": "Elastic Eats"
}
}
},
{
"match": {
"*": {
"query": "banana",
"zero_terms_query": "all"
}
}
}
]
}
}
}
我确定我遗漏了一些明显的东西,但是我已经阅读了手册,但我一点也不高兴。
更新:启用include_in_parent
嵌套对象适用于以下查询,但它会在内部复制肯定会影响内存的数据。
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"grocery_name": {
"query": "Elastic Eats"
}
}
},
{
"multi_match": {
"query": "banana"
}
}
]
}
}
}
有没有其他方法可以做到这一点?
解决方案
您需要使用带有 inner_hits 的嵌套匹配查询,从而导致内部嵌套查询自动匹配相关的嵌套级别,而不是根
搜索查询
{
"query": {
"bool": {
"filter": [
{
"term": {
"grocery_name": "elastic"
}
},
{
"nested": {
"path": "items",
"query": {
"bool": {
"must": [
{
"match": {
"items.name": "banana"
}
}
]
}
},
"inner_hits": {}
}
}
]
}
}
}
搜索结果:
"inner_hits": {
"items": {
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.744874,
"hits": [
{
"_index": "stof_64273970",
"_type": "_doc",
"_id": "1",
"_nested": {
"field": "items",
"offset": 0
},
"_score": 0.744874,
"_source": {
"name": "Red banana",
"stock": "12",
"category": "fruit"
}
},
{
"_index": "stof_64273970",
"_type": "_doc",
"_id": "1",
"_nested": {
"field": "items",
"offset": 1
},
"_score": 0.744874,
"_source": {
"name": "Cavendish banana",
"stock": "10",
"category": "fruit"
}
}
]
}
更新1:
根据您的评论,您可以针对您的用例使用多重匹配查询
如果未提供任何字段,则 multi_match 查询默认为 index.query.default_field 索引设置,而后者又默认为 *。
(*) 提取映射中符合术语查询条件的所有字段并过滤元数据字段。然后组合所有提取的字段以构建查询。
搜索查询:
{
"query": {
"bool": {
"filter": [
{
"term": {
"grocery_name": "elastic"
}
},
{
"nested": {
"path": "items",
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "banana" <-- note this
}
}
]
}
},
"inner_hits": {}
}
}
]
}
}
}
更新 2:
您需要使用多个 bool 查询的组合,如下所示:
{
"query": {
"bool": {
"must": [
{
"match_phrase": {
"grocery_name": {
"query": "Elastic Eats"
}
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "banana"
}
}
]
}
},
{
"bool": {
"must": [
{
"nested": {
"path": "items",
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "banana"
}
}
]
}
},
"inner_hits": {}
}
}
]
}
}
]
}
}
]
}
}
}
推荐阅读
- spring-boot - SpringBoot Config Server 文件分隔符问题
- c++ - 指针减去数组和变量中的指针
- php - 如何根据 json id 查询 Eloquent 关系表
- javascript - 在Vue中的方法内部调用方法
- agora.io - 如何在 agora.io 踢用户?
- python - 当行数据分为两个单独的页面时,如何正确地从pdf中提取表格数据?
- c - 标签页的文本没有正确显示 unicode 字符串
- python - aiohttp.web post 方法获取参数
- android - 为什么 Facebook 登录不适用于我的免安装应用?
- r - R中的子集数据框,dplyr过滤列A的行值而不是B列的行中的NA