ElasticSearch return 仅文档的特定部分
ElasticSearch return only specific part of the document
我有一个模仿以下结构的 JSON 文档。
{
"mydata": [
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
},
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line two",
"Key5": "of the file"
}]
}
我使用的索引本身没有任何特定的映射。我可以写一个自由文本的 Lucene 查询,比如
mydata.Key4:"line one"
结果是 return 整个文档。但是,就我而言,我只想检索 JSON 对象的第一部分作为结果。有办法实现吗?
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
}
我发现我可以使用 _source_includes
检索特定字段并传递所需的键,但是,我无法找到与 return 的特定部分中的所有键等效的JSON 与查询匹配的文档。是因为文件的索引方式吗?有人可以在这里指导我吗?
编辑:
我删除了我的索引并更新了映射如下
{
"mappings" : {
"properties" : {
"data" : {
"type" : "nested"
}
}
}
}
我重新索引了文档,快速浏览了 ES 文档和 运行 以下嵌套查询。
{
"_source": false,
"query": {
"nested": {
"path": "data",
"query": {
"match": {
"data.Key4": "line one"
}
},
"inner_hits": {}
}
}
}
但是,这也是 return 我索引中的所有文档,除了现在 returned 结果在 inner_hits
下
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.52889514,
"hits": [{
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_score": 0.52889514,
"inner_hits": {
"data": {
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.87546873,
"hits": [{
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_nested": {
"field": "data",
"offset": 0
},
"_score": 0.87546873,
"_source": {
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
}
}, {
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_nested": {
"field": "data",
"offset": 1
},
"_score": 0.18232156,
"_source": {
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line two",
"Key5": "of the file"
}
}]
}
}
}
}]
}
}
我是不是漏掉了什么?
因为您没有定义 mapping
,这是主要问题。当您按照您提到的方式保存数据时,它将作为 text
.
类型的单独属性保存
当您执行搜索时,它会带来整个文档。但是,如果您为 mydata
定义 nested
映射,那么您可以使用 inner_hits
来仅检索匹配的文档。
编辑:
要使用的查询:
{
"_source": false,
"query": {
"nested": {
"path": "data",
"inner_hits": {
},
"query": {
"bool": {
"must": [
{
"term": { //To look for exact match
"data.Key4.keyword": "line one" //need to match line one not line two
}
}
]
}
}
}
}
}
当你使用 match 时会发生什么:
line one
将被标记如下
{
"tokens": [
{
"token": "line",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "one",
"start_offset": 5,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 1
}
]
}
类似地,它创建了两个标记 line
、two
。
所以当你使用match
时,它是全文搜索查询。它确实分析了索引时间和搜索时间。因此在搜索期间,line one
将被分析,ES 将查找 line
或 one
。 line two
包含标记 line
因此这也是结果的一部分。
要避免这种情况,您必须避免分析。所以必须使用term queries
。它寻找完全匹配。
我有一个模仿以下结构的 JSON 文档。
{
"mydata": [
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
},
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line two",
"Key5": "of the file"
}]
}
我使用的索引本身没有任何特定的映射。我可以写一个自由文本的 Lucene 查询,比如
mydata.Key4:"line one"
结果是 return 整个文档。但是,就我而言,我只想检索 JSON 对象的第一部分作为结果。有办法实现吗?
{
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
}
我发现我可以使用 _source_includes
检索特定字段并传递所需的键,但是,我无法找到与 return 的特定部分中的所有键等效的JSON 与查询匹配的文档。是因为文件的索引方式吗?有人可以在这里指导我吗?
编辑:
我删除了我的索引并更新了映射如下
{
"mappings" : {
"properties" : {
"data" : {
"type" : "nested"
}
}
}
}
我重新索引了文档,快速浏览了 ES 文档和 运行 以下嵌套查询。
{
"_source": false,
"query": {
"nested": {
"path": "data",
"query": {
"match": {
"data.Key4": "line one"
}
},
"inner_hits": {}
}
}
}
但是,这也是 return 我索引中的所有文档,除了现在 returned 结果在 inner_hits
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.52889514,
"hits": [{
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_score": 0.52889514,
"inner_hits": {
"data": {
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.87546873,
"hits": [{
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_nested": {
"field": "data",
"offset": 0
},
"_score": 0.87546873,
"_source": {
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line one",
"Key5": "of the file"
}
}, {
"_index": "myindex",
"_type": "_doc",
"_id": "QAZJ-nMBi6fwNevjDQJy",
"_nested": {
"field": "data",
"offset": 1
},
"_score": 0.18232156,
"_source": {
"Key1": "Hello",
"Key2": "this",
"Key3": "is",
"Key4": "line two",
"Key5": "of the file"
}
}]
}
}
}
}]
}
}
我是不是漏掉了什么?
因为您没有定义 mapping
,这是主要问题。当您按照您提到的方式保存数据时,它将作为 text
.
当您执行搜索时,它会带来整个文档。但是,如果您为 mydata
定义 nested
映射,那么您可以使用 inner_hits
来仅检索匹配的文档。
编辑:
要使用的查询:
{
"_source": false,
"query": {
"nested": {
"path": "data",
"inner_hits": {
},
"query": {
"bool": {
"must": [
{
"term": { //To look for exact match
"data.Key4.keyword": "line one" //need to match line one not line two
}
}
]
}
}
}
}
}
当你使用 match 时会发生什么:
line one
将被标记如下
{
"tokens": [
{
"token": "line",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "one",
"start_offset": 5,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 1
}
]
}
类似地,它创建了两个标记 line
、two
。
所以当你使用match
时,它是全文搜索查询。它确实分析了索引时间和搜索时间。因此在搜索期间,line one
将被分析,ES 将查找 line
或 one
。 line two
包含标记 line
因此这也是结果的一部分。
要避免这种情况,您必须避免分析。所以必须使用term queries
。它寻找完全匹配。