Elasticsearch object nested join 數(shù)據(jù)類型

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ū)別


對比.png

以 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 查詢生效,解決了嵌套查詢的問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荐绝,一起剝皮案震驚了整個濱河市一汽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌低滩,老刑警劉巖召夹,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恕沫,居然都是意外死亡监憎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門婶溯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲸阔,“玉大人,你說我怎么就攤上這事迄委『稚福” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵跑筝,是天一觀的道長死讹。 經(jīng)常有香客問我,道長曲梗,這世上最難降的妖魔是什么赞警? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮虏两,結(jié)果婚禮上愧旦,老公的妹妹穿的比我還像新娘。我一直安慰自己定罢,他們只是感情好笤虫,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祖凫,像睡著了一般琼蚯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惠况,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天遭庶,我揣著相機與錄音,去河邊找鬼稠屠。 笑死峦睡,一個胖子當著我的面吹牛翎苫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榨了,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼煎谍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了龙屉?” 一聲冷哼從身側(cè)響起呐粘,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叔扼,沒想到半個月后事哭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡瓜富,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年鳍咱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片与柑。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡谤辜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出价捧,到底是詐尸還是另有隱情丑念,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布结蟋,位于F島的核電站脯倚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嵌屎。R本人自食惡果不足惜推正,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宝惰。 院中可真熱鬧植榕,春花似錦、人聲如沸尼夺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淤堵。三九已至寝衫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拐邪,已是汗流浹背竞端。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庙睡,地道東北人事富。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像乘陪,于是被迫代替她去往敵國和親统台。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容