Object 類型
在設(shè)計(jì)索引mapping時(shí),在某些業(yè)務(wù)下,需要設(shè)計(jì)的對(duì)象中包含對(duì)象,俗稱內(nèi)部對(duì)象,此時(shí)就可以使用Object類型來(lái)存儲(chǔ)對(duì)象.
以下定義了店鋪對(duì)象,包含店鋪名稱、店鋪編碼、供應(yīng)商信息,另外供應(yīng)商信息中又包含供應(yīng)商編碼、供應(yīng)商名稱。同時(shí)供應(yīng)商信息還包含自身的對(duì)象屬性所在區(qū)域,所在區(qū)域又包含省和市,這種定義才能滿足查詢店鋪信息、查詢供應(yīng)商所有店鋪信息,以及查詢某地區(qū)的所有店鋪信息等等場(chǎng)景。
#定義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"
}
}
}
}
}
}
}
}
#插入測(cè)試數(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對(duì)應(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),一個(gè)子文檔只能由一個(gè)父文檔,一個(gè)父文檔可以有多個(gè)子文檔。
#定義索引,my_goods_sale為售賣的上信息,my_goods_comment為商品的評(píng)價(jià)信息
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"
}
}
#添加商品售賣的評(píng)價(jià)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"
}
}
#添加商品售賣的評(píng)價(jià)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 的專用版本,允許對(duì)象數(shù)組以可以彼此獨(dú)立查詢的方式進(jìn)行索引。
ES 中其實(shí)是沒(méi)有內(nèi)部對(duì)象的概念,因此它將對(duì)象層次結(jié)構(gòu)簡(jiǎn)化為字段名稱和值,以列表的形式展現(xiàn)。
首先來(lái)比較 nester 與 parent/child 以及 Object 的區(qū)別

以 B2B 電商行業(yè)的實(shí)際業(yè)務(wù)場(chǎng)景來(lái)舉例說(shuō)明,2B 行業(yè)的交易具有一定封閉性,只有簽署合同、經(jīng)常往來(lái)交易的會(huì)員往往有更高資格的交易權(quán)、議價(jià)權(quán)。
定義商品索引,其中 groupPrice 標(biāo)識(shí)分組價(jià)對(duì)象,對(duì)象里面包含了 boxLevelPrice 分組價(jià)格、level 分組級(jí)別,當(dāng)前端業(yè)務(wù)線搜索時(shí),傳入用戶所在組級(jí)別,即可查詢對(duì)應(yīng)的價(jià)格。為了便于區(qū)分我們先定義為 Object 類型來(lái)觀察下現(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"
}
}
}
}
}
}
#插入測(cè)試數(shù)據(jù)
POST goods_info_object/_bulk
{"index":{"_id":1}}
{"goodsName":"美國(guó)蘋果","skuCode":"skuCode1","brandName":"美國(guó)蘋果","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組且價(jià)格等于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" : "美國(guó)蘋果",
"skuCode" : "skuCode1",
"brandName" : "美國(guó)蘋果",
"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ù)不是我們期望的,這是因?yàn)?ES 中將 Object 數(shù)組打平了做存儲(chǔ)導(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"
}
}
}
}
}
}
#插入同樣的測(cè)試數(shù)據(jù)
POST goods_info_nested/_bulk
{"index":{"_id":1}}
{"goodsName":"美國(guó)蘋果","skuCode":"skuCode1","brandName":"美國(guó)蘋果","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" : "美國(guó)蘋果",
"skuCode" : "skuCode1",
"brandName" : "美國(guó)蘋果",
"shopCode" : "sc00001",
"publicPrice" : "8388.88",
"groupPrice" : [
{
"boxLevelPrice" : "4888.00",
"level" : "A"
},
{
"boxLevelPrice" : "6888.00",
"level" : "B"
}
]
}
}
]
返回的是我們期望的,說(shuō)明 nested 查詢生效,解決了嵌套查詢的問(wèn)題