使用 Elasticsearch 从嵌套对象中过滤多个字段
Filtering on multiple fields from nested object with Elasticsearch
我是 Elasticsearch 的新手,我正在尝试编写一些查询,但碰巧不起作用。我有关于人的信息,我想根据一些属性查询人。
这是 Elasticsearch 中映射的一部分:
"properties": {
"doc": {
...
"languages": [{
"language": {
"type": "text",
"null_value": "NULL"
},
"level": {
"type": "integer",
"null_value": "NULL"
}
}],
...
}
}
比如我想过滤掉所有说英语且水平大于3和[=26=的人]日语 水平高于 2.
我已经尝试过的是这种方法并没有给出预期的结果。
"size": 1000,
"from": 0,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{"match": {"languages.language": "english"}},
{"range": {"languages.search_value": {"gt": 3}}}
]
}
},
{
"bool": {
"must": [
{"match": {"languages.language": "japanese"}},
{"range": {"languages.search_value": {"gt": 2}}}
]
}
}
]
}
}
以上查询returns所有说英语和日语的人,但语言水平不匹配。有些人会说 4 级英语(没问题),但日语会说 1 级(这不行),德语会说 5 级。我想问题在于,不是只为特定语言寻找想要的水平, 我的查询查找人们使用的所有语言的水平。
因此,我希望从查询中得到的结果是所有说英语 4 或 5 级和日语 3、4 或 5 级的人(都在同时)。我不关心他们说的其他语言和水平。
欢迎任何帮助或想法如何解决这个问题。
您需要使用 nested mapping 语言和级别。
映射
PUT /employee
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"languages": {
"type": "nested",
"properties": {
"language": {
"type": "text"
},
"level": {
"type": "integer"
}
}
}
}
}
}
数据:
[
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "vkVy9WwBecJvLwMRPgIH",
"_score" : 1.0,
"_source" : {
"name" : "User1",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 2
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "v0Vy9WwBecJvLwMRagL6",
"_score" : 1.0,
"_source" : {
"name" : "User2",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 1
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "wEVy9WwBecJvLwMRlQIs",
"_score" : 1.0,
"_source" : {
"name" : "User3",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Spanish",
"level" : 1
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "wUWD9WwBecJvLwMRWgIq",
"_score" : 1.0,
"_source" : {
"name" : "User4",
"languages" : [
{
"language" : "English",
"level" : 2
},
{
"language" : "French",
"level" : 1
}
]
}
}
]
查询
GET employee/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "languages",
"query": {
"bool": {
"must": [
{
"match": {
"languages.language": "English"
}
},
{
"range": {
"languages.level": {
"gte": 3
}
}
}
]
}
}
}
},
{
"nested": {
"path": "languages",
"query": {
"bool": {
"must": [
{
"match": {
"languages.language": "Japanese"
}
},
{
"range": {
"languages.level": {
"gte": 2
}
}
}
]
}
}
}
}
]
}
}
}
结果:
[
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "vkVy9WwBecJvLwMRPgIH",
"_score" : 3.974081,
"_source" : {
"name" : "User1",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 2
}
]
}
}
]
解决方案非常简单,您需要了解嵌套类型。 Link 在这个答案中对此有解释
我是 Elasticsearch 的新手,我正在尝试编写一些查询,但碰巧不起作用。我有关于人的信息,我想根据一些属性查询人。
这是 Elasticsearch 中映射的一部分:
"properties": {
"doc": {
...
"languages": [{
"language": {
"type": "text",
"null_value": "NULL"
},
"level": {
"type": "integer",
"null_value": "NULL"
}
}],
...
}
}
比如我想过滤掉所有说英语且水平大于3和[=26=的人]日语 水平高于 2.
我已经尝试过的是这种方法并没有给出预期的结果。
"size": 1000,
"from": 0,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{"match": {"languages.language": "english"}},
{"range": {"languages.search_value": {"gt": 3}}}
]
}
},
{
"bool": {
"must": [
{"match": {"languages.language": "japanese"}},
{"range": {"languages.search_value": {"gt": 2}}}
]
}
}
]
}
}
以上查询returns所有说英语和日语的人,但语言水平不匹配。有些人会说 4 级英语(没问题),但日语会说 1 级(这不行),德语会说 5 级。我想问题在于,不是只为特定语言寻找想要的水平, 我的查询查找人们使用的所有语言的水平。
因此,我希望从查询中得到的结果是所有说英语 4 或 5 级和日语 3、4 或 5 级的人(都在同时)。我不关心他们说的其他语言和水平。
欢迎任何帮助或想法如何解决这个问题。
您需要使用 nested mapping 语言和级别。
映射
PUT /employee
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"languages": {
"type": "nested",
"properties": {
"language": {
"type": "text"
},
"level": {
"type": "integer"
}
}
}
}
}
}
数据:
[
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "vkVy9WwBecJvLwMRPgIH",
"_score" : 1.0,
"_source" : {
"name" : "User1",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 2
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "v0Vy9WwBecJvLwMRagL6",
"_score" : 1.0,
"_source" : {
"name" : "User2",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 1
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "wEVy9WwBecJvLwMRlQIs",
"_score" : 1.0,
"_source" : {
"name" : "User3",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Spanish",
"level" : 1
}
]
}
},
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "wUWD9WwBecJvLwMRWgIq",
"_score" : 1.0,
"_source" : {
"name" : "User4",
"languages" : [
{
"language" : "English",
"level" : 2
},
{
"language" : "French",
"level" : 1
}
]
}
}
]
查询
GET employee/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "languages",
"query": {
"bool": {
"must": [
{
"match": {
"languages.language": "English"
}
},
{
"range": {
"languages.level": {
"gte": 3
}
}
}
]
}
}
}
},
{
"nested": {
"path": "languages",
"query": {
"bool": {
"must": [
{
"match": {
"languages.language": "Japanese"
}
},
{
"range": {
"languages.level": {
"gte": 2
}
}
}
]
}
}
}
}
]
}
}
}
结果:
[
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "vkVy9WwBecJvLwMRPgIH",
"_score" : 3.974081,
"_source" : {
"name" : "User1",
"languages" : [
{
"language" : "English",
"level" : 3
},
{
"language" : "Japanese",
"level" : 2
}
]
}
}
]
解决方案非常简单,您需要了解嵌套类型。 Link 在这个答案中对此有解释