通遼網(wǎng)站建設(shè)公司百度移動(dòng)點(diǎn)擊排名軟件
Nested 類型是 object 數(shù)據(jù)類型的特殊版本,它允許對(duì)象數(shù)組以一種可以彼此獨(dú)立查詢的方式進(jìn)行索引。在內(nèi)部,嵌套對(duì)象將數(shù)組中的每個(gè)對(duì)象索引為單獨(dú)的隱藏文檔,這意味著每個(gè)嵌套對(duì)象都可以使用 nested query 獨(dú)立于其他對(duì)象進(jìn)行查詢。每個(gè) nested 對(duì)象都被索引為一個(gè)單獨(dú)的 Lucene 文檔。有關(guān)更多關(guān)于 nested 數(shù)據(jù)類型的文檔,我們可以參考之前的文章 “Elasticsearch: object 及 nested 數(shù)據(jù)類型”。
在使用 Elasticsearch 時(shí),為了系統(tǒng)的效率,我們并不建議經(jīng)常修改文檔,但是在有些時(shí)候,我們還必須對(duì)已經(jīng)索引過(guò)的文檔進(jìn)行修改。針對(duì) nested 類型的字段,我該如何進(jìn)行更新及刪除呢?
讓我們先使用一個(gè)例子來(lái)進(jìn)行展示。
我們首先來(lái)創(chuàng)建一個(gè) developer 的索引:
PUT developer
{"mappings": {"properties": {"name": {"type": "text"},"skills": {"type": "nested","properties": {"language": {"type": "keyword"},"level": {"type": "keyword"}}}}}
}
在上面,我們定義 skills 為一個(gè) nested 數(shù)據(jù)類型。我們使用如下的命令來(lái)創(chuàng)建兩個(gè)文檔:
POST developer/_doc/101
{"name": "zhang san","skills": [{"language": "ruby","level": "expert"},{"language": "javascript","level": "beginner"}]
}POST developer/_doc/102
{"name": "li si","skills": [{"language": "ruby","level": "beginner"}]
}
上面的命令寫入了兩個(gè)文檔。
添加技能
針對(duì)第二個(gè)文檔,我們想增加如下的一個(gè)技能:
{"language": "Python","level" "expert"
}
首先讓我們使用 painless 語(yǔ)言創(chuàng)建我們的腳本。 你可以在參考資料中閱讀有關(guān)它的更多詳細(xì)信息,但熟悉 Java 的人會(huì)發(fā)現(xiàn)編碼很簡(jiǎn)單。關(guān)于 painless 語(yǔ)音的編程,你可以在文章 “Elastic:開發(fā)者上手指南” 中的 “Painless 編程” 章節(jié)中找到很多文章進(jìn)行參考。
我們的腳本將驗(yàn)證 skills 字段是否為空,如果是,我們創(chuàng)建列表實(shí)例并稍后添加新項(xiàng)目。如果不是,則添加新 skills。?
if (ctx._source.skills != null) {ctx._source.skills.addAll(params.skills);} else {ctx._source.skills = new ArrayList();ctx._source.skills.addAll(params.skills);}
最終添加 skills 的代碼是這樣的:
POST developer/_update/102
{"script": {"source": """if (ctx._source.skills != null) {ctx._source.skills.addAll(params.skills);} else {ctx._source.skills = new ArrayList();ctx._source.skills.addAll(params.skills);}""","params": {"skills": [{"language": "Python","level": "expert"}]}}
}
我們通過(guò)如下的命令來(lái)進(jìn)行驗(yàn)證:
GET developer/_doc/102
我們得到如下的結(jié)果:
{"_index": "developer","_id": "102","_version": 3,"_seq_no": 4,"_primary_term": 1,"found": true,"_source": {"name": "li si","skills": [{"language": "ruby","level": "beginner"},{"level": "expert","language": "Python"}]}
}
從上面,我們可以看出來(lái)新的 skills 已經(jīng)被添加進(jìn)去了。
刪除 skills
同樣,我們可以使用如下的代碼來(lái)刪除一個(gè)技能:
POST developer/_update/102
{"script": {"source": """if (ctx._source.skills != null) {for (int i; i < params.skills.length; i++) {ctx._source.skills.removeIf(a->a.language.equals(params.skills[i].language) &&a.level.equals(params.skills[i].level));}}""","params": {"skills": [{"language": "Python","level": "expert"}]}}
}
我們?cè)俅问褂萌缦碌拿顏?lái)查看 id 為 102 的文檔:
GET developer/_doc/102
上面的命令返回的值為:
{"_index": "developer","_id": "102","_version": 4,"_seq_no": 5,"_primary_term": 1,"found": true,"_source": {"name": "li si","skills": [{"language": "ruby","level": "beginner"}]}
}
我們可以看出來(lái),在上一步添加的 skill,現(xiàn)在已經(jīng)被成功地移除了。