Nested 類型是 object 數(shù)據(jù)類型的特殊版本,它允許對象數(shù)組以一種可以彼此獨立查詢的方式進(jìn)行索引。在內(nèi)部,嵌套對象將數(shù)組中的每個對象索引為單獨的隱藏文檔,這意味著每個嵌套對象都可以使用 nested query 獨立于其他對象進(jìn)行查詢。每個 nested 對象都被索引為一個單獨的 Lucene 文檔。有關(guān)更多關(guān)于 nested 數(shù)據(jù)類型的文檔,我們可以參考之前的文章 “Elasticsearch: object 及 nested 數(shù)據(jù)類型”。
在使用 Elasticsearch 時,為了系統(tǒng)的效率,我們并不建議經(jīng)常修改文檔,但是在有些時候,我們還必須對已經(jīng)索引過的文檔進(jìn)行修改。針對 nested 類型的字段,我該如何進(jìn)行更新及刪除呢?
讓我們先使用一個例子來進(jìn)行展示。
我們首先來創(chuàng)建一個 developer 的索引:
PUT developer
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"skills": {
"type": "nested",
"properties": {
"language": {
"type": "keyword"
},
"level": {
"type": "keyword"
}
}
}
}
}
}
在上面,我們定義 skills 為一個 nested 數(shù)據(jù)類型。我們使用如下的命令來創(chuàng)建兩個文檔:
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"
}
]
}
上面的命令寫入了兩個文檔。
添加技能
針對第二個文檔,我們想增加如下的一個技能:
{
"language": "Python",
"level" "expert"
}
首先讓我們使用 painless 語言創(chuàng)建我們的腳本。 你可以在參考資料中閱讀有關(guān)它的更多詳細(xì)信息,但熟悉 Java 的人會發(fā)現(xiàn)編碼很簡單。關(guān)于 painless 語音的編程,你可以在文章 “Elastic:開發(fā)者上手指南” 中的 “Painless 編程” 章節(jié)中找到很多文章進(jìn)行參考。
我們的腳本將驗證 skills 字段是否為空,如果是,我們創(chuà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"
}
]
}
}
}
我們通過如下的命令來進(jì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"
}
]
}
}
從上面,我們可以看出來新的 skills 已經(jīng)被添加進(jìn)去了。
刪除 skills
同樣,我們可以使用如下的代碼來刪除一個技能:
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"
}
]
}
}
}
我們再次使用如下的命令來查看 id 為 102 的文檔:
GET developer/_doc/102
上面的命令返回的值為:文章來源:http://www.zghlxwxcb.cn/news/detail-623953.html
{
"_index": "developer",
"_id": "102",
"_version": 4,
"_seq_no": 5,
"_primary_term": 1,
"found": true,
"_source": {
"name": "li si",
"skills": [
{
"language": "ruby",
"level": "beginner"
}
]
}
}
我們可以看出來,在上一步添加的 skill,現(xiàn)在已經(jīng)被成功地移除了。文章來源地址http://www.zghlxwxcb.cn/news/detail-623953.html
到了這里,關(guān)于Elasticsearch:如何修改 nested 字段的值的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!