nested
嵌套類型
數(shù)據(jù)的某個值是json、object對象;不再是簡單的數(shù)據(jù)類型,或者簡單數(shù)據(jù)類型的數(shù)組;那么還用之前的查詢方式就有問題了。因為ES在存儲復(fù)雜類型的時候會把對象的復(fù)雜層次結(jié)果扁平化為一個鍵值對列表 。此時,需要用nested進(jìn)行查詢
扁平化存儲
?
?用法
使用nested查詢的時候,在設(shè)置mapping的時候,也要指定字段類型為nested
PUT <index_name>
{
"mappings": {
"properties": {
"<nested_field_name>": {
"type": "nested"
}
}
}
}
查詢?
GET /my-index-000001/_search
{
"query": {
"nested": {
"path": "obj1",
"query": {
"bool": {
"must": [
{ "match": { "obj1.name": "blue" } },
{ "range": { "obj1.count": { "gt": 5 } } }
]
}
},
"score_mode": "avg"
}
}
}
path:nested對象的查詢深度
score_mode:評分計算方式
avg (默認(rèn)):使用所有匹配的子對象的平均相關(guān)性得分。
max:使用所有匹配的子對象中的最高相關(guān)性得分。
min:使用所有匹配的子對象中最低的相關(guān)性得分。
none:不要使用匹配的子對象的相關(guān)性分?jǐn)?shù)。該查詢?yōu)楦肝臋n分配得分為0。
sum:將所有匹配的子對象的相關(guān)性得分相加。
Join
父子級關(guān)系?
join和nested一樣,需要在設(shè)置mapping的時候,設(shè)置字段類型
mapping
PUT msb_depart
{
"mappings": {
"properties": {
"msb_join_field": {
"type": "join",
"relations": {
"depart": "employee"
}
},
"my_id": {
"type": "keyword"
}
}
}
}
插入父級數(shù)據(jù)
PUT msb_depart/_doc/1
{
"my_id": 1,
"name":"教學(xué)部",
"msb_join_field":{
"name":"depart"
}
}
PUT msb_depart/_doc/2
{
"my_id": 2,
"name":"咨詢部",
"msb_join_field":{
"name":"depart"
}
}
連接數(shù)據(jù)類型是一個特殊字段,它在同一索引的文檔中創(chuàng)建父/子關(guān)系。關(guān)系部分在文檔中定義了一組可能的關(guān)系,每個關(guān)系是一個父名和一個子名
插入子級數(shù)據(jù)需要指定routing路由,因為父文檔和子文檔必須在同一個分片建立索引
插入子級數(shù)據(jù)
PUT msb_depart/_doc/3?routing=1&refresh
{
"my_id": 3,
"name":"馬老師",
"msb_join_field":{
"name":"employee",
"parent":1
}
}
PUT msb_depart/_doc/4?routing=1&refresh
{
"my_id": 4,
"name":"周老師",
"msb_join_field":{
"name":"employee",
"parent":1
}
}
搜索所有父級數(shù)據(jù)
GET msb_depart/_search
{
"query": {
"has_child": {
"type": "employee",
"query": {
"match_all": {}
}
}
}
}
搜索所有子級
{
"query": {
"has_parent": {
"parent_type": "depart",
"query": {
"match": {
"name.keyword": "咨詢部"
}
}
}
}
}
join
類型不能像關(guān)系數(shù)據(jù)庫中的表鏈接那樣去用,不論是has_child
或者是has_parent
查詢都會對索引的查詢性能有嚴(yán)重的負(fù)面影響。并且會觸發(fā)global ordinals
join
唯一合適應(yīng)用場景是:當(dāng)索引數(shù)據(jù)包含一對多的關(guān)系,并且其中一個實體的數(shù)量遠(yuǎn)遠(yuǎn)超過另一個的時候。
關(guān)聯(lián)關(guān)系處理優(yōu)先級
Object>nested>join
Object類型
通俗點就是通過字段冗余,以一張大寬表來實現(xiàn)粗粒度的index,這樣可以充分發(fā)揮扁平化的優(yōu)勢。但是這是以犧牲索引性能及靈活度為代價的。
使用的前提:冗余的字段應(yīng)該是很少改變的;比較適合與一對少量關(guān)系的處理。
當(dāng)業(yè)務(wù)數(shù)據(jù)庫并非采用非規(guī)范化設(shè)計時,這時要將數(shù)據(jù)同步到作為二級索引庫的ES中,就很難使用上述增量同步方案,必須進(jìn)行定制化開發(fā),基于特定業(yè)務(wù)進(jìn)行應(yīng)用開發(fā)來處理join關(guān)聯(lián)和實體拼接
嵌套對象
索引性能和查詢性能二者不可兼得,必須進(jìn)行取舍。嵌套文檔將實體關(guān)系嵌套組合在單文檔內(nèi)部(類似與json的一對多層級結(jié)構(gòu))
這種方式犧牲索引性能(文檔內(nèi)任一屬性變化都需要重新索引該文檔)來換取查詢性能,可以同時返回關(guān)系實體,比較適合于一對少量的關(guān)系處理。當(dāng)使用嵌套文檔時,使用通用的查詢方式是無法訪問到的,必須使用合適的查詢方式(nested query、nested filter、nested facet等),很多場景下,使用嵌套文檔的復(fù)雜度在于索引階段對關(guān)聯(lián)關(guān)系的組織拼裝
父子級關(guān)系
父子文檔犧牲了一定的查詢性能來換取索引性能,適用于一對多的關(guān)系處理。其通過兩種type的文檔來表示父子實體,父子文檔的索引是獨立的。父-子文檔ID映射存儲在 Doc Values 中。當(dāng)映射完全在內(nèi)存中時, Doc Values 提供對映射的快速處理能力,另一方面當(dāng)映射非常大時,可以通過溢出到磁盤提供足夠的擴(kuò)展能力。 在查詢parent-child替代方案時,發(fā)現(xiàn)了一種filter-terms的語法,要求某一字段里有關(guān)聯(lián)實體的ID列表?;镜脑硎窃趖erms的時候,對于多項取值,如果在另外的index或者type里已知主鍵id的情況下,某一字段有這些值,可以直接嵌套查詢。文章來源:http://www.zghlxwxcb.cn/news/detail-593513.html
具體可參考官方文檔的示例:通過用戶里的粉絲關(guān)系,微博和用戶的關(guān)系,來查詢某個用戶的粉絲發(fā)表的微博列表。文章來源地址http://www.zghlxwxcb.cn/news/detail-593513.html
到了這里,關(guān)于Elasticsearch--查詢(nested、join)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!