簡體   English   中英

elasticsearch腳本來檢查字段是否存在並創建它

[英]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'是列表

如果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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM