[英]elasticsearch script to check if field exists and create it
我創建了一個腳本,該腳本以彈性方式記錄了應用於文檔的標簽的歷史記錄。 標記的名稱是動態的,因此當我嘗試將當前標記移動到“歷史記錄”字段時,對於沒有歷史記錄字段的標記,它會失敗。
這是將當前標簽復制到標簽歷史記錄字段的腳本:
script:"ctx._source.tags[params.tagName.toString()].history.add(ctx._source.tags[params.tagName.toString()].current)"
這是文檔的樣子:
"tags": {
"relevant": {
"current": {
"tagDate": 1501848372292,
"taggedByUser": "dev",
"tagActive": true
},
"history": [
{
"tagDate": 1501841137822,
"taggedByUser": "admin",
"tagActive": true
},
{
"tagDate": 1501841334127,
"taggedByUser": "admin",
"tagActive": true
},
}}}}
用戶可以動態添加新標簽,所以我想做的是創建一個不存在的歷史對象,然后填充它。
Elasticsearch腳本的可用文檔很少,因此我希望明智的人知道答案,因為我確信檢查字段並創建它是彈性腳本語言的基本內容。
更新
因此,在重新考慮了該索引的結構之后,我想實現以下目標:
tags:[
{hot:
{current:{tagDate:1231231233, taggedbyUser: user1, tagStatus: true},
history:[ {tagDate:123444433, taggedbyUser: user1, tagStatus: true},
{tagDate:1234412433, taggedbyUser: user1, tagStatus: true}
]
}
{interesting:
{current:{tagDate:1231231233, taggedbyUser: user1, tagStatus: true},
history:[ {tagDate:123444433, taggedbyUser: user1, tagStatus: true},
{tagDate:1234412433, taggedbyUser: user1, tagStatus: true}
]
}
]
在此示例中,標簽名稱為“熱門”和“有趣”,但是用戶將能夠輸入所需的任何標簽名稱,因此這些標簽名稱絕不是預定義的。 當用戶用彈性標簽文檔時,所應用的標簽已經以彈性標簽存在,它應該將“當前”標簽更多地添加到“歷史”數組中,然后用新值覆蓋“當前”標簽。
感謝您迄今為止的答復,但是示例代碼對我不起作用。
我認為我遇到的問題是,首先,代碼將需要遍歷所有標簽並獲取名稱。 然后,我想將每個參數與我在參數中提供的名稱進行比較。 我認為這是第一個問題出現的地方。
然后,我需要將“當前”對象移動到“歷史”數組。 這里似乎也有問題。 我正在嘗試使用“ ctx._source.tags [i] .history.add(params.param1),但是未添加任何內容。
有什么想法嗎?
謝謝!
這有點復雜,因為您需要在腳本中做三件事:
history
不存在,則初始化數組 current
用新的標簽 假設您的初始文檔看起來像這樣(請注意沒有history
):
{
"_id": "AV2uvqCUfGXyNt1PjTbb",
"tags": {
"relevant": {
"current": {
"tagDate": 1501848372292,
"taggedByUser": "dev",
"tagActive": true
}
}
}
}
為了能夠執行這三個步驟,您需要運行以下腳本:
curl -X POST \
http://127.0.0.1:9200/script/test/AV2uvqCUfGXyNt1PjTbb/_update \
-d '{
"script": {
"inline": "if (ctx._source.tags.get(param2).history == null) ctx._source.tags.get(param2).history = new ArrayList(); ctx._source.tags.get(param2).history.add(ctx._source.tags.get(param2).current); ctx._source.tags.get(param2).current = param1;",
"params" : {
"param1" : {
"tagDate": 1501848372292,
"taggedByUser": "my_user",
"tagActive": true
},
"param2": "relevant"
}
}
}'
結果是:
{
"_id": "AV2uvqCUfGXyNt1PjTbb",
"_source": {
"tags": {
"relevant": {
"current": {
"tagActive": true,
"tagDate": 1501848372292,
"taggedByUser": "my_user"
},
"history": [
{
"tagDate": 1501848372292,
"taggedByUser": "dev",
"tagActive": true
}
]
}
}
}
}
使用parm1
(新標記)的新內容運行相同的腳本將得到:
{
"_id": "AV2uvqCUfGXyNt1PjTbb",
"_source": {
"tags": {
"relevant": {
"current": {
"tagActive": true,
"tagDate": 1501841334127,
"taggedByUser": "admin"
},
"history": [
{
"tagDate": 1501848372292,
"taggedByUser": "dev",
"tagActive": true
},
{
"tagActive": true,
"tagDate": 1501848372292,
"taggedByUser": "my_user"
}
]
}
}
}
}
如果tags
是“內部json對象”的列表,例如:
{
"tags": [
{
"relevant": {
"current": {
"tagDate": 1501841334127,
"taggedByUser": "dev",
"tagActive": true
}
}
},
{
"new_tag": {
"current": {
"tagDate": 1501848372292,
"taggedByUser": "admin",
"tagActive": true
}
}
}
]
}
您必須遍歷列表以找到正確元素的索引。 假設您要更新元素new_tag
。 首先,您需要檢查此標記是否存在-如果存在,請獲取其索引,如果不存在,請從腳本返回。 有了索引,只需獲取正確的元素,就可以像以前一樣進行操作了。 該腳本如下所示:
int num = -1;
for (int i = 0; i < ctx._source.tags.size(); i++) {
if (ctx._source.tags.get(i).get(param2) != null) {
num = i;
break;
};
};
if (num == -1) {
return;
};
if (ctx._source.tags.get(num).get(param2).history == null)
ctx._source.tags.get(num).get(param2).history = new ArrayList();
ctx._source.tags.get(num).get(param2).history.add(ctx._source.tags.get(num).get(param2).current);
ctx._source.tags.get(num).get(param2).current = param1;
和wole查詢:
curl -X POST \
http://127.0.0.1:9200/script/test/AV29gAnpqbJMKVv3ij7U/_update \
-d '{
"script": {
"inline": "int num = -1; for (int i = 0; i < ctx._source.tags.size(); i++) {if (ctx._source.tags.get(i).get(param2) != null) {num = i; break;};}; if (num == -1) {return;}; if (ctx._source.tags.get(num).get(param2).history == null) ctx._source.tags.get(num).get(param2).history = new ArrayList(); ctx._source.tags.get(num).get(param2).history.add(ctx._source.tags.get(num).get(param2).current); ctx._source.tags.get(num).get(param2).current = param1;",
"params" : {
"param1" : {
"tagDate": 1501848372292,
"taggedByUser": "my_user",
"tagActive": true
},
"param2": "new_tag"
}
}
}
'
結果:
{
"tags": [
{
"relevant": {
"current": {
"tagDate": 1501841334127,
"taggedByUser": "dev",
"tagActive": true
}
}
},
{
"new_tag": {
"current": {
"tagActive": true,
"tagDate": 1501848372292,
"taggedByUser": "my_user"
},
"history": [
{
"tagDate": 1501848372292,
"taggedByUser": "admin",
"tagActive": true
}
]
}
}
]
}
我認為您可以在groovy腳本中執行類似的操作
{
"script": "if( ctx._source.containsKey(\"field_name\") ){ ctx.op = \"none\"} else{ctx._source.field_name= field_value;}"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.