尊敬的弹性搜索专家,
我在查询嵌套对象时遇到问题。允许使用以下简化映射:
{
"mappings" : {
"_doc" : {
"properties" : {
"companies" : {
"type": "nested",
"properties" : {
"company_id": { "type": "long" },
"name": { "type": "text" }
}
},
"title": { "type": "text" }
}
}
}
}
并将一些文档放在索引中:
PUT my_index/_doc/1
{
"title" : "CPU release",
"companies" : [
{ "company_id" : 1, "name" : "AMD" },
{ "company_id" : 2, "name" : "Intel" }
]
}
PUT my_index/_doc/2
{
"title" : "GPU release 2018-01-10",
"companies" : [
{ "company_id" : 1, "name" : "AMD" },
{ "company_id" : 3, "name" : "Nvidia" }
]
}
PUT my_index/_doc/3
{
"title" : "GPU release 2018-03-01",
"companies" : [
{ "company_id" : 3, "name" : "Nvidia" }
]
}
PUT my_index/_doc/4
{
"title" : "Chipset release",
"companies" : [
{ "company_id" : 2, "name" : "Intel" }
]
}
现在我想执行这样的查询:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "GPU" } },
{ "nested": {
"path": "companies",
"query": {
"bool": {
"must": [
{ "match": { "companies.name": "AMD" } }
]
}
},
"inner_hits" : {}
}
}
]
}
}
}
因此,我想得到匹配的公司与数量匹配的文件。因此,上面的查询应该会告诉我:
[
{ "company_id" : 1, "name" : "AMD", "matched_documents:": 1 }
]
以下查询:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "GPU" } }
{ "nested": {
"path": "companies",
"query": { "match_all": {} },
"inner_hits" : {}
}
}
]
}
}
}
应该给我所有公司分配到一个文件,其标题包含“GPU”与匹配的文件数量:
[
{ "company_id" : 1, "name" : "AMD", "matched_documents:": 1 },
{ "company_id" : 3, "name" : "Nvidia", "matched_documents:": 2 }
]
如果表现良好,是否有可能实现这一结果?我显然对匹配的文档不感兴趣,只对匹配文档和嵌套对象的数量感兴趣。
谢谢你的帮助。
就弹性搜索而言,你需要做的是:
title
中包含GPU
,或者在公司
列表中提及Nvidia
);company_id
)对"嵌套"文档进行分组;数组中的每个嵌套
对象都作为单独的隐藏文档进行索引,这会使生活变得复杂一些。让我们看看如何对它们进行聚合。
您可以通过嵌套、术语和top_hits聚合的组合来实现此目的:
POST my_index/doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "GPU"
}
},
{
"nested": {
"path": "companies",
"query": {
"match_all": {}
}
}
}
]
}
},
"aggs": {
"Extract nested": {
"nested": {
"path": "companies"
},
"aggs": {
"By company id": {
"terms": {
"field": "companies.company_id"
},
"aggs": {
"Examples of such company_id": {
"top_hits": {
"size": 1
}
}
}
}
}
}
}
}
这将给出以下输出:
{
...
"hits": { ... },
"aggregations": {
"Extract nested": {
"doc_count": 4, <== How many "nested" documents there were?
"By company id": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 3, <== this bucket's key: "company_id": 3
"doc_count": 2, <== how many "nested" documents there were with such company_id?
"Examples of such company_id": {
"hits": {
"total": 2,
"max_score": 1.5897496,
"hits": [ <== an example, "top hit" for such company_id
{
"_nested": {
"field": "companies",
"offset": 1
},
"_score": 1.5897496,
"_source": {
"company_id": 3,
"name": "Nvidia"
}
}
]
}
}
},
{
"key": 1,
"doc_count": 1,
"Examples of such company_id": {
"hits": {
"total": 1,
"max_score": 1.5897496,
"hits": [
{
"_nested": {
"field": "companies",
"offset": 0
},
"_score": 1.5897496,
"_source": {
"company_id": 1,
"name": "AMD"
}
}
]
}
}
}
]
}
}
}
}
请注意,对于< code>Nvidia,我们有< code >“doc _ count”:2 。
但是,如果我们想计算得到Nvidia
与Intel
这可以通过< code>reverse_nested
聚合来实现。
我们需要稍微修改一下我们的查询:
POST my_index/doc/_search
{
"query": { ... },
"aggs": {
"Extract nested": {
"nested": {
"path": "companies"
},
"aggs": {
"By company id": {
"terms": {
"field": "companies.company_id"
},
"aggs": {
"Examples of such company_id": {
"top_hits": {
"size": 1
}
},
"original doc count": { <== we ask ES to count how many there are parent docs
"reverse_nested": {}
}
}
}
}
}
}
}
结果将如下所示:
{
...
"hits": { ... },
"aggregations": {
"Extract nested": {
"doc_count": 3,
"By company id": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 3,
"doc_count": 2,
"original doc count": {
"doc_count": 2 <== how many "parent" documents have such company_id
},
"Examples of such company_id": {
"hits": {
"total": 2,
"max_score": 1.5897496,
"hits": [
{
"_nested": {
"field": "companies",
"offset": 1
},
"_score": 1.5897496,
"_source": {
"company_id": 3,
"name": "Nvidia"
}
}
]
}
}
},
{
"key": 1,
"doc_count": 1,
"original doc count": {
"doc_count": 1
},
"Examples of such company_id": {
"hits": {
"total": 1,
"max_score": 1.5897496,
"hits": [
{
"_nested": {
"field": "companies",
"offset": 0
},
"_score": 1.5897496,
"_source": {
"company_id": 1,
"name": "AMD"
}
}
]
}
}
}
]
}
}
}
}
为了使区别更加明显,让我们稍微更改一下数据,并在文档列表中添加另一个< code>Nvidia项目:
PUT my_index/doc/2
{
"title" : "GPU release 2018-01-10",
"companies" : [
{ "company_id" : 1, "name" : "AMD" },
{ "company_id" : 3, "name" : "Nvidia" },
{ "company_id" : 3, "name" : "Nvidia" }
]
}
最后一个查询(带有< code>reverse_nested的查询)将给出以下内容:
"By company id": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 3,
"doc_count": 3, <== 3 "nested" documents with Nvidia
"original doc count": {
"doc_count": 2 <== but only 2 "parent" documents
},
"Examples of such company_id": {
"hits": {
"total": 3,
"max_score": 1.5897496,
"hits": [
{
"_nested": {
"field": "companies",
"offset": 2
},
"_score": 1.5897496,
"_source": {
"company_id": 3,
"name": "Nvidia"
}
}
]
}
}
},
如您所见,这是一个难以理解的细微差异,但它完全改变了语义。
虽然在大多数情况下,嵌套
查询和聚合的性能应该足够了,但它当然会带来一定的成本。因此,在调整搜索速度时,建议避免使用嵌套
或父子类型。
在Elasticsearch中,最佳性能通常是通过非规范化实现的,尽管没有单一的配方,您应该根据需要选择数据模型。
希望这能为您澄清这个嵌套
的事情!
问题内容: 这是我在elasticsearch中存储在索引上的数据类型。我必须找到包含主要成分牛肉(且重量小于1000)和成分-(辣椒粉且重量小于250),(橄榄油和重量小于300)以及所有其他成分类似的食谱。 索引的映射是 我的查询是 但这给了Null。有人可以帮我吗?我认为我没有正确使用嵌套查询 问题答案: 试试这个:
我试图创建一个嵌套查询,它将过滤掉一些带有特定术语的文档。在本例中,我试图过滤掉在user.first中有匹配术语的文档。数据示例: 我的查询没有得到所需的结果,因为它返回给我所有未筛选的记录。我尝试使用: 我希望这里得到与过滤器不匹配的文档。在这种情况下,它应该只返回第二个文档。做这件事的正确方法是什么?
问题内容: 如何转换这种查询。 使用QueryBuilders进行Java客户端查询 问题答案: 以下Java代码将生成您的查询 参数为: 参数为:
问题内容: 我正在尝试使用query_string编写查询以检索嵌套对象的数据查询。 我想做的查询的一个例子是: 其中“ a”是嵌套对象,“ id”是“ a”的字段。 我知道我可以使用嵌套查询成功地执行此任务,编写如下查询: 但是,我想避免这种情况。我不想自己弄清楚用户正在搜索嵌套字段并修改查询。我尝试使用“ fields”参数,但它似乎不适用于嵌套对象。 是否可以使用“ query_string
我有一个带有嵌套映射的索引。我想预先形成一个查询,该查询将返回以下内容:给我搜索词中每个单词出现在一个或多个嵌套文档中的所有文档。 以下是索引: 以下是我尝试的最新查询: 例如,如果我搜索单词“食物和水”,我希望每个单词至少出现在嵌套文档中。即使只有一个单词存在,当前搜索也会返回文档 谢谢你的帮助! 更新:正如克里斯托所建议的,解决方案有效。现在我有以下问题。 这是我的索引: 我要执行的查询是,如
问题内容: 我在获取与Elasticsearch一起使用的嵌套查询时遇到问题(如果我删除了查询字符串之一,则可以使用)。我要解决的问题是我有一个包含关闭列表的文档(关闭)。我想在条件满足另一个值的闭包列表中搜索一个值。那只是从argan = 1的闭包中获得价值 我正在得到这个错误响应; 我的映射如下所示。 有人知道我在做什么错吗? 问题答案: 您的查询不是有效的查询。您需要使用适当的复合查询将其他