我尝试在脚本评分中使用嵌套值,但无法正常工作,因为我无法通过doc访问字段来遍历字段。此外,当我尝试在Kibana(如_type:images AND _exists_:colors
)中查询它时,它将不匹配任何文档,即使当我单独查看所有文档时,该字段在所有文档中都清晰可见,但是我可以使用params._source来访问它,但是我读过,它可以很慢很慢,并不是真的推荐。
我知道这个问题完全是由于我们创建这个嵌套字段的方式造成的,所以如果我不能找到比这更好的方法,我将不得不重新索引我们的2 m+文档,看看我是否能找到另一种解决问题的方法,但我希望避免这种情况,同时也只是更好地理解Elastic在幕后是如何工作的,以及为什么它会以这种方式工作。
我在这里提供的例子并不是我的真实的生活问题,但也描述了这个问题。假设我们有一个描述图像的文档。该文档有一个字段,其中包含图像中存在多少红色、蓝色和绿色的值。
创建索引和文档的请求,这些文档具有包含颜色数组的嵌套字段,这些颜色数组之间以100磅分隔:
PUT images
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"_doc": {
"properties": {
"id" : { "type" : "integer" },
"title" : { "type" : "text" },
"description" : { "type" : "text" },
"colors": {
"type": "nested",
"properties": {
"red": {
"type": "double"
},
"green": {
"type": "double"
},
"blue": {
"type": "double"
}
}
}
}
}
}
}
PUT images/_doc/1
{
"id" : 1,
"title" : "Red Image",
"description" : "Description of Red Image",
"colors": [
{
"red": 100
},
{
"green": 0
},
{
"blue": 0
}
]
}
PUT images/_doc/2
{
"id" : 2,
"title" : "Green Image",
"description" : "Description of Green Image",
"colors": [
{
"red": 0
},
{
"green": 100
},
{
"blue": 0
}
]
}
PUT images/_doc/3
{
"id" : 3,
"title" : "Blue Image",
"description" : "Description of Blue Image",
"colors": [
{
"red": 0
},
{
"green": 0
},
{
"blue": 100
}
]
}
现在,如果我使用doc运行此查询:
GET images/_search
{
"query": {
"function_score": {
"functions": [
{
"script_score": {
"script": {
"source": """
boolean debug = true;
for(color in doc["colors"]) {
if (debug === true) {
throw new Exception(color["red"].toString());
}
}
"""
}
}
}
]
}
}
}
我将得到异常No field found for [colors] in mapping with types []
,但如果我使用params._source,如下所示:
GET images/_search
{
"query": {
"function_score": {
"functions": [
{
"script_score": {
"script": {
"source": """
boolean debug = true;
for(color in params._source["colors"]) {
if (debug === true) {
throw new Exception(color["red"].toString());
}
}
"""
}
}
}
]
}
}
}
我可以输出"caused_by": {"type": "exception", "reason": "100"}
,所以我知道它工作了,因为第一个文档是红色的,值为100。
我甚至不确定这是否属于一个问题,但更多的是一种求助。如果有人能解释为什么会这样,并给予解决问题的最佳方法,我将非常感激。
(另外,一些在Painless中调试的技巧也会很棒!!!)
2条答案
按热度按时间mf98qq941#
在Elasticsearch的评分脚本
"script_score": {"script": {"source": "..." }}
中,您可以使用param._source
对象访问嵌套值。例如,如果您的
documents
索引包含以下文档:下面的查询将以随机顺序返回100个文档,优先选择主题为
sports
的文档:aor9mmx12#
不要担心
params._source
的速度慢'-这是您唯一的选择,因为迭代doc
的嵌套上下文只允许访问单个嵌套颜色。试试看:
无痛评分上下文为here。
第二,您已经非常接近手动抛出异常了--不过有一种更干净的方法可以做到这一点。取消注解
Debug.explain(color);
,您就可以开始了。还有一件事,我特意添加了一个
match
查询来提高分数,但更重要的是,为了说明查询是如何在后台构建的--当您在GET images/_validate/query?explain
下重新运行上面的查询时,您将亲眼看到。