讓my-index-0成為別名為my-index的 ES索引。
它具有以下映射:
{
"my-index-0": {
"aliases": {
"my-index": {}
},
"mappings": {
"doc": {
"properties": {
"foo": {
"properties": {
"fizz": {
"type": "keyword"
},
"baz": {
"type": "keyword"
}
}
}
}
}
}
}
}
假設我想baz從foo. 我正在使用以下步驟:
my-index-1使用更新的映射(foo.baz已洗掉)創建一個新索引PUT /my-index-1
{
"mappings": {
"doc": {
"properties": {
"foo": {
"properties": {
"fizz": {
"type": "keyword"
},
}
}
}
}
}
}
- 重新索引資料從
my-index-0到my-index-1使用POST /_reindex
{
"source": {
"index": "my-index-0"
},
"dest": {
"index": "my-index-1"
}
}
- 使用
my-index別名將別名移動到my-index-1索引POST /_aliases
{
"actions": [
{"remove": {"index": "my-index-0", "alias": "my-index"}},
{"add": {"index": "my-index-1", "alias": "my-index"}},
]
}
預期結果
新索引中的資料沒有該foo.baz屬性。
實際結果
在my-index-1創作,它的映射中不包含的foo.baz領域,然而,再后指數化,my-index-1的映射更改為舊索引“映射。
注意:_source可用于簡單的欄位洗掉
如果要洗掉一個欄位,例如bar從下面的映射中洗掉
{
"mappings": {
"foo": {
"type": "text"
},
"bar": {
"type": "text"
}
}
}
在重新索引 API 的請求中提供_source沒有bar欄位的引數就足夠了:
{
"source": {
"index": "my-index-0",
"_source": ["foo"]
},
"dest": {
"index": "my-index-1"
}
}
如何使用嵌套結構實作相同的目標?
uj5u.com熱心網友回復:
當您使用reindexES 時,嘗試將所有資料從源索引復制到目標索引。如果您想讓您的索引不被修改,您需要將此行添加到您的映射中:
"dynamic" : "strict"
現在如果你想要reindex資料,你會得到一個錯誤,"strict_dynamic_mapping_exception"因為"mapping set to strict, dynamic introduction of [baz] within [foo] is not allowed". 所以你需要reindex像這樣洗掉這個欄位:
POST _reindex
{
"source": {
"index": "my-index-0"
},
"dest": {
"index": "my-index-1"
},
"script": {
"source": "ctx._source.remove(\"foo.baz\")"
}
}
注意:添加"dynamic" : "strict"是可選的,可以防止您的索引被修改。如果您只是編輯reindex查詢,它將對您有用。
uj5u.com熱心網友回復:
我想我已經找到了我正在尋找的通用解決方案。
在_source屬性,可以顯式地指定每一個嵌套的領域,因此,_source對于本例中的場景值應該是["foo.fiz"]-注意缺乏"foo.bar"這不應該被復制。
{
"source": {
"index": "my-index-0",
"_source": ["foo.fiz"]
},
"dest": {
"index": "my-index-1"
}
}
本質上,"_source"為一般情況生成屬性的問題可以簡化為找到舊映射和新映射的所有屬性路徑集的交集。
Python解決方案
下面的函式遞回地遍歷屬性并生成所有屬性路徑。
def get_property_path(properties: dict[str, Any], name: str = "") -> Iterator[str]:
for property_name, property_value in properties.items():
new_name = f"{name}.{property_name}" if name else property_name
if nested_properties := property_value.get("properties"):
yield from get_property_path(nested_properties, new_name)
else:
yield new_name
例如
>>> properties = {
"a": {
"properties": {
"b": {
"properties": {
"c": {"type": "text"},
},
},`
},
},
"e": {
"properties": {
"f": {"type": "text"},
},
},
}
>>> list(get_property_path(properties))
>>> ['a.b.c', 'e.f']
它可以稍后用于計算應復制的欄位集(舊映射和新映射中的欄位):
_source = list(
set(get_property_path(old_mapping["properties"]))
& set(get_property_path(new_mapping["properties"]))
)
I won't accept my answer tho, as there might be a simpler solution that is based on the ES API.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/338106.html
