假设一个商品搜索的场景,一个商品有多个供应商,不同的供应商可能有不同的价格和配送等标签,怎么为商品及其店铺配送属性建立索引?一种方法是将商品*店铺平铺,但此种方法缺点有1)当商品基本属性修改时,需要更新多个doc(每个店铺都要更新),2)索引量比较大。我们采用另外一种方法:父子索引和查询。
1)定义索引结构
put http://localhost:9200/upcs
{
"mappings": {
"properties": {
"title": {
"type": "text"
},
"upc": {
"type": "keyword"
},
"store": {
"type": "keyword"
},
"tags": {
"type": "keyword"
},
"price":{
"type":"integer"
},
"my_join": {
"type": "join",
"relations": {
"upc": "sales"
}
}
}
}
}
2)初始化测试数据
put http://localhost:9200/upcs/_bulk
{"index":{"_id":"upc1"}}
{"upc":"upc1","title":"test double test","my_join":{"name":"upc"}}
{"index":{"_id":"upc2"}}
{"upc":"upc2","title":"the second test","my_join":{"name":"upc"}}
{"index":{"_id":"upc3"}}
{"upc":"upc3","title":"third test ok","my_join":{"name":"upc"}}
{"index":{"_id":"sales1","routing":"upc1"}}
{"upc":"upc1","store":"s1","price":80,"tags":["t#1","t#2"],"my_join":{"name":"sales","parent":"upc1"}}
{"index":{"_id":"sales2","routing":"upc1"}}
{"upc":"upc1","store":"s2","price":81,"tags":["t#3","t#4"],"my_join":{"name":"sales","parent":"upc1"}}
{"index":{"_id":"sales3","routing":"upc2"}}
{"upc":"upc2","store":"s1","price":82,"tags":["t#5","t#6"],"my_join":{"name":"sales","parent":"upc2"}}
{"index":{"_id":"sales4","routing":"upc2"}}
{"upc":"upc2","store":"s2","price":83,"tags":["t#7","t#8"],"my_join":{"name":"sales","parent":"upc2"}}
{"index":{"_id":"sales5","routing":"upc3"}}
{"upc":"upc3","store":"s3","price":84,"tags":["t#1","t#2"],"my_join":{"name":"sales","parent":"upc3"}}
3)执行父子查询
post http://localhost:9200/upcs/_search
{
"_source": [
"upc",
"store",
"price"
],
"explain": false,
"query": {
"bool": {
"must": [
{
"has_parent": {
"parent_type": "upc",
"score": true,
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "test",
"fields": [
"title^5"
],
"type": "cross_fields",
"minimum_should_match": "50%"
}
}
]
}
}
}
}
],
"filter": {
"bool": {
"must": [
{
"range": {
"price": {
"gte": 60,
"lte": 95
}
}
},
{
"bool": {
"should": [
{
"term": {
"store": "s2"
}
},
{
"term": {
"store": "s1"
}
}
]
}
},
{
"bool": {
"should": [
{
"bool":{
"must":[
{"term":{"store":"s1"}},
{"term":{"tags":"t#1"}}
]
}
},
{
"bool":{
"must":[
{"term":{"store":"s3"}},
{"term":{"tags":"t#1"}}
]
}
}
]
}
}
]
}
}
}
}
}