Object 類型
在設(shè)計索引mapping時,在某些業(yè)務(wù)下行您,需要設(shè)計的對象中包含對象铭乾,俗稱內(nèi)部對象,此時就可以使用Object類型來存儲對象.
以下定義了店鋪對象娃循,包含店鋪名稱炕檩、店鋪編碼、供應(yīng)商信息捌斧,另外供應(yīng)商信息中又包含供應(yīng)商編碼笛质、供應(yīng)商名稱。同時供應(yīng)商信息還包含自身的對象屬性所在區(qū)域捞蚂,所在區(qū)域又包含省和市妇押,這種定義才能滿足查詢店鋪信息、查詢供應(yīng)商所有店鋪信息姓迅,以及查詢某地區(qū)的所有店鋪信息等等場景敲霍。
#定義mapping
PUT my_shop_0425
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 1
}
},
"mappings": {
"properties": {
"shopName": {
"type": "text",
"analyzer": "ik_smart"
},
"shopCode": {
"type": "keyword"
},
"supplier": {
"properties": {
"supplier_code": {
"type": "keyword"
},
"supplier_name": {
"type": "text",
"analyzer": "ik_smart"
},
"area": {
"properties": {
"province": {
"type": "keyword"
},
"city": {
"type": "keyword"
}
}
}
}
}
}
}
}
#插入測試數(shù)據(jù)
POST my_shop_0425/_bulk
{"index":{"_id":1}}
{"shopName":"蘋果熱銷店鋪","shopCode":"sc001","supplier":{"supplier_code":"001","supplier_name":"南京農(nóng)村電商領(lǐng)導(dǎo)者","area":{"province":"江蘇省","city":"南京市"}}}
{"index":{"_id":2}}
{"shopName":"美的熱銷店鋪","shopCode":"sc002","supplier":{"supplier_code":"001","supplier_name":"南京農(nóng)村電商領(lǐng)導(dǎo)者","area":{"province":"江蘇省","city":"南京市"}}}
{"index":{"_id":3}}
{"shopName":"金沙酒熱銷店鋪","shopCode":"sc003","supplier":{"supplier_code":"002","supplier_name":"山東農(nóng)村電商領(lǐng)導(dǎo)者","area":{"province":"江蘇省","city":"南京市"}}}
{"index":{"_id":4}}
{"shopName":"華為熱銷店鋪","shopCode":"sc004","supplier":{"supplier_code":"002","supplier_name":"山東農(nóng)村電商領(lǐng)導(dǎo)者","area":{"province":"山東省","city":"青島市"}}}
2家供應(yīng)商
南京農(nóng)村電商領(lǐng)導(dǎo)者 店鋪:蘋果熱銷店鋪+美的熱銷店鋪
山東農(nóng)村電商領(lǐng)導(dǎo)者 店鋪:金沙酒熱銷店鋪+華為熱銷店鋪
查詢供應(yīng)商001對應(yīng)的所有店鋪:
POST my_shop_0425/_search
{
"query": {
"match": {
"supplier.supplier_code": "001"
}
}
}
#返回
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.6931471,
"hits" : [
{
"_index" : "my_shop_0425",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.6931471,
"_source" : {
"shopName" : "蘋果熱銷店鋪",
"shopCode" : "sc001",
"supplier" : {
"supplier_code" : "001",
"supplier_name" : "南京農(nóng)村電商領(lǐng)導(dǎo)者",
"area" : {
"province" : "江蘇省",
"city" : "南京市"
}
}
}
},
{
"_index" : "my_shop_0425",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.6931471,
"_source" : {
"shopName" : "美的熱銷店鋪",
"shopCode" : "sc002",
"supplier" : {
"supplier_code" : "001",
"supplier_name" : "南京農(nóng)村電商領(lǐng)導(dǎo)者",
"area" : {
"province" : "江蘇省",
"city" : "南京市"
}
}
}
}
]
}
}
#查詢銷售區(qū)域在南京的所有店鋪
#查詢銷售區(qū)域在南京的所有店鋪
POST my_shop_0425/_search
{
"query": {
"match": {
"supplier.area.city": "南京市"
}
}
}
#返回
{
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.35667494,
"hits" : [
{
"_index" : "my_shop_0425",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.35667494,
"_source" : {
"shopName" : "蘋果熱銷店鋪",
"shopCode" : "sc001",
"supplier" : {
"supplier_code" : "001",
"supplier_name" : "南京農(nóng)村電商領(lǐng)導(dǎo)者",
"area" : {
"province" : "江蘇省",
"city" : "南京市"
}
}
}
},
{
"_index" : "my_shop_0425",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.35667494,
"_source" : {
"shopName" : "美的熱銷店鋪",
"shopCode" : "sc002",
"supplier" : {
"supplier_code" : "001",
"supplier_name" : "南京農(nóng)村電商領(lǐng)導(dǎo)者",
"area" : {
"province" : "江蘇省",
"city" : "南京市"
}
}
}
},
{
"_index" : "my_shop_0425",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.35667494,
"_source" : {
"shopName" : "金沙酒熱銷店鋪",
"shopCode" : "sc003",
"supplier" : {
"supplier_code" : "002",
"supplier_name" : "山東農(nóng)村電商領(lǐng)導(dǎo)者",
"area" : {
"province" : "江蘇省",
"city" : "南京市"
}
}
}
}
]
}
}
Join 類型
Join 類型是一種特殊的類型,類似父子結(jié)構(gòu)丁存,一個子文檔只能由一個父文檔肩杈,一個父文檔可以有多個子文檔。
#定義索引解寝,my_goods_sale為售賣的上信息扩然,my_goods_comment為商品的評價信息
PUT my_goods_hot_sale
{
"mappings": {
"properties": {
"my_id": {
"type": "keyword"
},
"my_join_field": {
"type": "join",
"relations": {
"my_goods_sale": "my_goods_comment"
}
}
}
}
}
#添加商品售賣ID為1的信息
PUT my_goods_hot_sale/_doc/1?refresh
{
"my_id": "1",
"text": "This is a my_goods_sale",
"my_join_field": {
"name": "my_goods_sale"
}
}
#添加商品售賣ID為2的信息
PUT my_goods_hot_sale/_doc/2?refresh
{
"my_id": "2",
"text": "This is another my_goods_sale",
"my_join_field": {
"name": "my_goods_sale"
}
}
#添加商品售賣的評價3,父商品為1
PUT my_goods_hot_sale/_doc/3?routing=1&refresh
{
"my_id": "3",
"text": "This is an comment",
"my_join_field": {
"name": "my_goods_comment",
"parent": "1"
}
}
#添加商品售賣的評價4聋伦,父商品為1
PUT my_goods_hot_sale/_doc/4?routing=1&refresh
{
"my_id": "4",
"text": "This is another comment",
"my_join_field": {
"name": "my_goods_comment",
"parent": "1"
}
}
- 根據(jù)父文檔查詢子文檔
GET my_goods_hot_sale/_search
{
"query": {
"has_parent": {
"parent_type": "my_goods_sale",
"query": {
"match": {
"text": "my_goods_sale"
}
}
}
}
}
- 根據(jù)子文檔查詢父文檔
GET my_goods_hot_sale/_search
{
"query": {
"has_child": {
"type": "my_goods_comment",
"query": {
"match_all": {}
}
}
}
}
Nested 類型
nested 是 object 的專用版本夫偶,允許對象數(shù)組以可以彼此獨立查詢的方式進行索引。
ES 中其實是沒有內(nèi)部對象的概念觉增,因此它將對象層次結(jié)構(gòu)簡化為字段名稱和值兵拢,以列表的形式展現(xiàn)。
首先來比較 nester 與 parent/child 以及 Object 的區(qū)別
以 B2B 電商行業(yè)的實際業(yè)務(wù)場景來舉例說明抑片,2B 行業(yè)的交易具有一定封閉性卵佛,只有簽署合同、經(jīng)常往來交易的會員往往有更高資格的交易權(quán)敞斋、議價權(quán)。
定義商品索引疾牲,其中 groupPrice 標識分組價對象植捎,對象里面包含了 boxLevelPrice 分組價格、level 分組級別阳柔,當前端業(yè)務(wù)線搜索時焰枢,傳入用戶所在組級別,即可查詢對應(yīng)的價格。為了便于區(qū)分我們先定義為 Object 類型來觀察下現(xiàn)象:
定義分組為 Object 類型
PUT goods_info_object
{
"mappings": {
"properties": {
"goodsName": {
"type": "text",
"analyzer": "ik_smart"
},
"skuCode": {
"type": "keyword"
},
"brandName": {
"type": "keyword"
},
"shopCode": {
"type": "keyword"
},
"publicPrice": {
"type": "float"
},
"groupPrice": {
"properties": {
"boxLevelPrice": {
"type": "keyword"
},
"level": {
"type": "keyword"
}
}
}
}
}
}
#插入測試數(shù)據(jù)
POST goods_info_object/_bulk
{"index":{"_id":1}}
{"goodsName":"美國蘋果","skuCode":"skuCode1","brandName":"美國蘋果","shopCode":"sc00001","publicPrice":"8388.88","groupPrice":[{"boxLevelPrice":"4888.00","level":"A"},{"boxLevelPrice":"6888.00","level":"B"}]}
{"index":{"_id":2}}
{"goodsName":"山東蘋果","skuCode":"skuCode2","brandName":"山東蘋果","shopCode":"sc00001","publicPrice":"7388.88","groupPrice":[{"boxLevelPrice":"5888.00","level":"A"},{"boxLevelPrice":"4888.00","level":"B"}]}
#檢索A組且價格等于4888.00的商品
POST goods_info_object/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"groupPrice.level": "A"
}
},
{
"match": {
"groupPrice.boxLevelPrice": "4888.00"
}
}
]
}
}
}
#返回:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.45840856,
"hits" : [
{
"_index" : "goods_info_object",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.45840856,
"_source" : {
"goodsName" : "美國蘋果",
"skuCode" : "skuCode1",
"brandName" : "美國蘋果",
"shopCode" : "sc00001",
"publicPrice" : "8388.88",
"groupPrice" : [
{
"boxLevelPrice" : "4888.00",
"level" : "A"
},
{
"boxLevelPrice" : "6888.00",
"level" : "B"
}
]
}
},
{
"_index" : "goods_info_object",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.45840856,
"_source" : {
"goodsName" : "山東蘋果",
"skuCode" : "skuCode2",
"brandName" : "山東蘋果",
"shopCode" : "sc00001",
"publicPrice" : "7388.88",
"groupPrice" : [
{
"boxLevelPrice" : "5888.00",
"level" : "A"
},
{
"boxLevelPrice" : "4888.00",
"level" : "B"
}
]
}
}
]
}
}
顯然返回的數(shù)據(jù)不是我們期望的济锄,這是因為 ES 中將 Object 數(shù)組打平了做存儲導(dǎo)致
定義分組為 Nested 類型
PUT goods_info_nested
{
"mappings": {
"properties": {
"goodsName": {
"type": "text",
"analyzer": "ik_smart"
},
"skuCode": {
"type": "keyword"
},
"brandName": {
"type": "keyword"
},
"shopCode": {
"type": "keyword"
},
"publicPrice": {
"type": "float"
},
"groupPrice": {
"type": "nested",
"properties": {
"boxLevelPrice": {
"type": "keyword"
},
"level": {
"type": "keyword"
}
}
}
}
}
}
#插入同樣的測試數(shù)據(jù)
POST goods_info_nested/_bulk
{"index":{"_id":1}}
{"goodsName":"美國蘋果","skuCode":"skuCode1","brandName":"美國蘋果","shopCode":"sc00001","publicPrice":"8388.88","groupPrice":[{"boxLevelPrice":"4888.00","level":"A"},{"boxLevelPrice":"6888.00","level":"B"}]}
{"index":{"_id":2}}
{"goodsName":"山東蘋果","skuCode":"skuCode2","brandName":"山東蘋果","shopCode":"sc00001","publicPrice":"7388.88","groupPrice":[{"boxLevelPrice":"5888.00","level":"A"},{"boxLevelPrice":"4888.00","level":"B"}]}
#查詢
POST goods_info_nested/_search
{
"query": {
"nested": {
"path": "groupPrice",
"query": {
"bool": {
"must": [
{
"match": {
"groupPrice.level": "A"
}
},
{
"match": {
"groupPrice.boxLevelPrice": "4888.00"
}
}
]
}
}
}
}
}
#返回:
"hits" : [
{
"_index" : "goods_info_nested",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862942,
"_source" : {
"goodsName" : "美國蘋果",
"skuCode" : "skuCode1",
"brandName" : "美國蘋果",
"shopCode" : "sc00001",
"publicPrice" : "8388.88",
"groupPrice" : [
{
"boxLevelPrice" : "4888.00",
"level" : "A"
},
{
"boxLevelPrice" : "6888.00",
"level" : "B"
}
]
}
}
]
返回的是我們期望的暑椰,說明 nested 查詢生效,解決了嵌套查詢的問題