我可以将标签添加到 Elastic Search 文档中的 "deeper" 键吗?
Can i add tags to a "deeper" key in an Elastic Search document?
我有带标签的产品,标签在标签类型中。
这是我添加到索引中的示例文档
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1219",
"_score" : 1.0,
"_source" : {
"id" : "1219",
"product_no" : "26426492261",
"merchant_id" : 11,
"name" : "Apple »Magic Keyboard für das 12,9\" iPad Pro (4. Generation)« iPad-Tastatur",
"category" : "Technik>Multimedia>Zubehör>Tastatur>iPad Tastatur",
"deep_link" : "https://foo",
"short_description" : null,
"long_description" : "Apple:",
"brand" : "Apple",
"merchant_image_url" : "http://something",
"tagtypes" : [
[
{
"Memory" : [ ]
}
]
]
}
},
标记类型“Memory”是在索引产品时动态创建的。
我尝试向该键添加标签
//attach tags also to ES
$params = [
'index' => 'products',
'id' => $product['_id'],
'body' => [
'script' => [
'source' => 'if (!ctx._source.tagtypes.'.$tagType->name.'.contains(params.tag)) { ctx._source.tagtypes.'.$tagType->name.'.add(params.tag) }',
'lang' => 'painless',
'params' => [
'tag' => $tag->value
]
]
]
];
但是我收到了类似
的错误
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"failed to execute script"}],"type":"illegal_argument_exception","reason":"failed to execute script","caused_by":{"type":"script_exception","reason":"runtime error","script_stack":["if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { "," ^---- HERE"],"script":"if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { ctx._source.tagtypes[\"Memory\"].add(params.tag) }","lang":"painless","position":{"offset":16,"start":0,"end":60},"caused_by":{"type":"wrong_method_type_exception","reason":"cannot convert MethodHandle(List,int)int to (Object,String)String"}}},"status":400}
谁能帮我解决这个问题。我找不到任何关于它的文档,因为示例通常太基础了。
通常可以像这样保存到“更深的键”吗?
或者我可以将“标签”创建为简单列表(没有任何深度)
提前致谢
阿德里安!
您的字段 tagtypes
是对象数组的数组,对象数组本身包含一键数组。
当你处理这种“深层”结构时,你需要一些形式的迭代来更新它们。
For
循环是一个很好的起点,但它们通常会导致 java.util.ConcurrentModificationExceptions
。因此,使用数据的临时副本更容易,然后在完成迭代后替换相应的 _source
属性:
{
"query": {
"match_all": {}
},
"script": {
"source": """
if (ctx._source.tagtypes == null) { return; }
def originalTagtypes = ctx._source.tagtypes;
def newTagtypes = [];
for (outerGroup in originalTagtypes) {
// keep what we've got
newTagtypes.addAll(outerGroup);
// group already present?
def atLeastOneGroupContainsTag = outerGroup.stream().anyMatch(tagGroup -> tagGroup.containsKey(params.tag));
// if not, add it as a hashmap of one single empty list
if (!atLeastOneGroupContainsTag) {
Map m = new HashMap();
m.put(params.tag, []);
newTagtypes.add(m);
}
}
ctx._source.tagtypes = [newTagtypes];
""",
"lang": "painless",
"params": {
"tag": "CPU"
}
}
}
这将最终像这样更新 tagtypes
:
{
...
"tagtypes" : [
[
{
"Memory" : [ ]
},
{
"CPU" : [ ] <---
}
]
],
...
}
您说文档示例太基础了,您说得对。无耻插件:我最近 published a handbook 旨在解决这个问题。您会发现许多重要的脚本示例,以更好地理解 Painless 脚本语言。
我有带标签的产品,标签在标签类型中。
这是我添加到索引中的示例文档
{
"_index" : "products",
"_type" : "_doc",
"_id" : "1219",
"_score" : 1.0,
"_source" : {
"id" : "1219",
"product_no" : "26426492261",
"merchant_id" : 11,
"name" : "Apple »Magic Keyboard für das 12,9\" iPad Pro (4. Generation)« iPad-Tastatur",
"category" : "Technik>Multimedia>Zubehör>Tastatur>iPad Tastatur",
"deep_link" : "https://foo",
"short_description" : null,
"long_description" : "Apple:",
"brand" : "Apple",
"merchant_image_url" : "http://something",
"tagtypes" : [
[
{
"Memory" : [ ]
}
]
]
}
},
标记类型“Memory”是在索引产品时动态创建的。
我尝试向该键添加标签
//attach tags also to ES
$params = [
'index' => 'products',
'id' => $product['_id'],
'body' => [
'script' => [
'source' => 'if (!ctx._source.tagtypes.'.$tagType->name.'.contains(params.tag)) { ctx._source.tagtypes.'.$tagType->name.'.add(params.tag) }',
'lang' => 'painless',
'params' => [
'tag' => $tag->value
]
]
]
];
但是我收到了类似
的错误{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"failed to execute script"}],"type":"illegal_argument_exception","reason":"failed to execute script","caused_by":{"type":"script_exception","reason":"runtime error","script_stack":["if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { "," ^---- HERE"],"script":"if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { ctx._source.tagtypes[\"Memory\"].add(params.tag) }","lang":"painless","position":{"offset":16,"start":0,"end":60},"caused_by":{"type":"wrong_method_type_exception","reason":"cannot convert MethodHandle(List,int)int to (Object,String)String"}}},"status":400}
谁能帮我解决这个问题。我找不到任何关于它的文档,因为示例通常太基础了。
通常可以像这样保存到“更深的键”吗? 或者我可以将“标签”创建为简单列表(没有任何深度)
提前致谢 阿德里安!
您的字段 tagtypes
是对象数组的数组,对象数组本身包含一键数组。
当你处理这种“深层”结构时,你需要一些形式的迭代来更新它们。
For
循环是一个很好的起点,但它们通常会导致 java.util.ConcurrentModificationExceptions
。因此,使用数据的临时副本更容易,然后在完成迭代后替换相应的 _source
属性:
{
"query": {
"match_all": {}
},
"script": {
"source": """
if (ctx._source.tagtypes == null) { return; }
def originalTagtypes = ctx._source.tagtypes;
def newTagtypes = [];
for (outerGroup in originalTagtypes) {
// keep what we've got
newTagtypes.addAll(outerGroup);
// group already present?
def atLeastOneGroupContainsTag = outerGroup.stream().anyMatch(tagGroup -> tagGroup.containsKey(params.tag));
// if not, add it as a hashmap of one single empty list
if (!atLeastOneGroupContainsTag) {
Map m = new HashMap();
m.put(params.tag, []);
newTagtypes.add(m);
}
}
ctx._source.tagtypes = [newTagtypes];
""",
"lang": "painless",
"params": {
"tag": "CPU"
}
}
}
这将最终像这样更新 tagtypes
:
{
...
"tagtypes" : [
[
{
"Memory" : [ ]
},
{
"CPU" : [ ] <---
}
]
],
...
}
您说文档示例太基础了,您说得对。无耻插件:我最近 published a handbook 旨在解决这个问题。您会发现许多重要的脚本示例,以更好地理解 Painless 脚本语言。