首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ElasticSearch:基于属性和嵌套对象的query_string多字段查询

ElasticSearch:基于属性和嵌套对象的query_string多字段查询
EN

Stack Overflow用户
提问于 2018-07-10 08:28:50
回答 1查看 1.2K关注 0票数 1

我试图解决以下高层次需求:

  • 在已经具有属性的文档上保存任意数目的键值对:名称和描述
  • 值可以是应该是“范围搜索”的数字。
  • 值可以包括需要“地理搜索”的geo_points。

我创建了以下索引。

代码语言:javascript
复制
{
    "settings": {
        "index" : {
            "number_of_shards" : 3, 
            "number_of_replicas" : 1
        }
    },
    "mappings": {
        "_doc": {
            "dynamic": "strict",
            "properties": {
                "name": {
                    "type": "text",
                    "analyzer": "german",
                },
                "description": {
                    "type": "text",
                    "analyzer": "german"
                },
                "attributes": {
                    "type": "nested",
                    "properties": {
                        "key": { "type": "text" },
                        "val_bool":   { "type": "boolean" },
                        "val_int":    { "type": "integer" },
                        "val_float":  { "type": "float" },
                        "val_string": { "type": "text" },
                        "val_geo":    { "type": "geo_point" },
                        "val_date":   { "type": "date" }
                    }
                }
            }
        }
    }
}

我们使用嵌套对象来保存每个文档的键值对列表。每个键值对使用一个类型化val_*属性来持久化类型化值.因此,启用对特殊类型的特殊搜索,例如范围查询。

为了在文档中搜索,我们使用query_string查询来允许用户在搜索中非常具体。例如。搜索文档的名称:foo和描述:bar。(如预期那样起作用)

同样的情况在键值对中也是可能的,例如: attributes.key:someKey和attributes.val_string:someStringValue。此场景需要一个嵌套查询,我们使用该查询并按预期工作。

不起作用的东西:,如果我们搜索名称:foo和attributes.key:someKey,我们就得不到结果。

似乎“嵌套query_string查询”和“只是query_string查询”在组合中不受支持。这是真的吗?实现所描述的需求的可行解决方案是什么?

该查询如下所示:

代码语言:javascript
复制
{
    "query": {
        "bool": {
            "should": [
                {
                    "query_string": {
                        "query": "attributes.key:someKey AND name:foo",
                        "default_operator": "and",
                        "fields": [
                            "name",
                            "description"
                        ]
                    }
                },
                {
                    "nested": {
                        "query": {
                            "query_string": {
                                "query": "attributes.key:someKey AND name:foo",
                                "default_operator": "and",
                                "fields": [
                                    "attributes.key",
                                    "attributes.val_string"
                                ]
                            }
                        },
                        "path": "attributes"
                    }
                }
            ]
        }
    }
}

任何帮助都是非常感谢的。提前谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-06 06:04:37

嵌套对象作为单独的文档进行索引。也就是说,您实际上是在查询两个文档,但它们都不匹配给定的查询:

_doc没有(非嵌套)字段属性,属性也不包含字段名。由于查询中的两个术语都与AND有逻辑链接,所以搜索结果的点击量为零。

在试图检索包含两个具有指定键之一的两个嵌套对象的所有根父文档时,像attributes.key:someKey AND attributes.key:otherKey这样的查询字符串也会出现类似的问题。因为两个嵌套对象是相互独立的,所以这个查询是在寻找一个带有两个键的嵌套对象--但是每个对象只能有一个。

要解决这个问题,您必须将查询分成与根父文档和嵌套对象相关的部分。之后,您必须为引用嵌套对象的每个术语创建一个嵌套查询。换句话说,name:foo AND attributes.key:someKey最终必须是这样的:

代码语言:javascript
复制
{
    "query": {
        "bool": {
            "must": [
                {
                    "query_string": {
                        "query": "name:foo"       
                    }
                },
                {
                    "nested": {
                        "query": {
                            "query_string": {
                                "query": "attributes.key:someKey"
                            }
                        },
                        "path": "attributes"
                    }
                }
            ]
        }
    }
}

一种可能的解决方案是提供几个输入,一个用于查询根父文档本身,另一个用于查询嵌套对象。然后,通过手动创建一个由嵌套部分和非嵌套部分组成的查询,可以组合这两个查询字符串。

或者,您可以考虑自己解析查询,每次遇到attributes.field时都生成嵌套查询。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51260521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档