一,数据结构
"properties": {
"type": { "type": "keyword" } ,
"title": { "type": "text", "analyzer": "ik_smart" },
"long_title": { "type": "text", "analyzer": "ik_smart" },
"category_id": { "type": "integer" },
"category": { "type": "keyword" },
"category_path": { "type": "keyword" },
"description": { "type": "text", "analyzer": "ik_smart" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"on_sale": { "type": "boolean" },
"rating": { "type": "float" },
"sold_count": { "type": "integer" },
"review_count": { "type": "integer" },
"skus": {
"type": "nested",
"properties": {
"title": { "type": "text", "analyzer": "ik_smart" },
"description": { "type": "text", "analyzer": "ik_smart"},
"price": { "type": "scaled_float", "scaling_factor": 100 }
}
},
"properties": {
"type": "nested",
"properties": {
"name": { "type": "keyword" },
"value": { "type": "keyword" }
}
}
}
此时我们想查询在skus中存在或者properties中存在的某个匹配的值,skus和properties都是nested嵌套对象类型的,想要的匹配条件并非在一个nested中,如果使用查询
{
"query": {
"nested": {
"path": "skus",
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "256G",
"fields": [
"skus.title",
"skus.description",
"properties.value"
]
}
}
]
}
}
}
}
}
来查询,并不能得到我们的预期(properties.name中有256G)。如果要硬写查询DSL那就更复杂了。我们可以使用copy_to来优化一下结构。
"properties": {
"type": { "type": "keyword" } ,
"title": { "type": "text", "analyzer": "ik_smart" },
"long_title": { "type": "text", "analyzer": "ik_smart" },
"category_id": { "type": "integer" },
"category": { "type": "keyword" },
"category_path": { "type": "keyword" },
"description": { "type": "text", "analyzer": "ik_smart" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"on_sale": { "type": "boolean" },
"rating": { "type": "float" },
"sold_count": { "type": "integer" },
"review_count": { "type": "integer" },
"skus": {
"type": "nested",
"properties": {
"title": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_title" },
"description": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_description" },
"price": { "type": "scaled_float", "scaling_factor": 100 }
}
},
"properties": {
"type": "nested",
"properties": {
"name": { "type": "keyword" },
"value": { "type": "keyword", "copy_to": "properties_value" }
}
}
}
给properties.title加上了copy_to参数,值是skus_title,Elasticsearch 就会把这个字段值复制到 skus_title 字段里,这样就可以在 multi_match 的 fields 里通过 skus_title 来匹配。skus.description 和 properties.name 同理。(修改了mapping后一定要记得重新同步数据)
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "256G",
"fields": [
"skus_title",
"skus_description",
"properties_value"
]
}
}
]
}
}
}
使用此查询语句即可获得正确的数据。