我试图找出如何解决这两个问题,我有我的ES 5. 6指数。
"mappings": {
"my_test": {
"properties": {
"Employee": {
"type": "nested",
"properties": {
"Name": {
"type": "keyword",
"normalizer": "lowercase_normalizer"
},
"Surname": {
"type": "keyword",
"normalizer": "lowercase_normalizer"
}
}
}
}
}
}
字符串
我需要创建两个单独的脚本过滤器:
1 -筛选employee数组大小为== 3的文档
2 -过滤数组第一个元素为“Name”==“John”的文档
我试图做一些第一步,但我无法遍历列表。我总是有一个空指针异常错误。
{
"bool": {
"must": {
"nested": {
"path": "Employee",
"query": {
"bool": {
"filter": [
{
"script": {
"script" : """
int array_length = 0;
for(int i = 0; i < params._source['Employee'].length; i++)
{
array_length +=1;
}
if(array_length == 3)
{
return true
} else
{
return false
}
"""
}
}
]
}
}
}
}
}
}
型
2条答案
按热度按时间tzcvj98z1#
正如瓦尔所注意到的,在最近版本的Elasticsearch中,你不能在脚本查询中访问
_source
文档。但是elasticsearch允许你在“score context”中访问这个_source
。因此,一个可能的解决方法(但需要注意性能)是在查询中使用脚本分数和min_score。
你可以在elasticsearch中通过嵌套字段值的总和查询文档的堆栈溢出post中找到这种行为的例子。
在您的情况下,这样的查询可以完成这项工作:
字符串
但是请记住,正如瓦尔已经提到的那样,它可能对您的集群非常沉重。您应该通过在
function_score query
中添加过滤器(在我的示例中为match_all)来缩小设置范围,将脚本应用于该文档。在任何情况下,这都不是Elasticsearch应该使用的方式,你不能指望这样一个被黑客攻击的查询有出色的表现。ljsrvy3e2#
1 -筛选employee数组大小为== 3的文档
对于第一个问题,最好的办法是添加另一个根级别字段(例如
NbEmployees
),它包含Employee
数组中的项数,这样您就可以使用range
查询,而不是代价高昂的script
查询。然后,每当修改
Employee
数组时,也会相应地更新NbEmployees
字段。效率更高!2 -过滤数组第一个元素为“Name”==“John”的文档
关于这一点,你需要知道嵌套字段在Lucene中是独立的(隐藏的)文档,所以没有办法在同一个查询中一次访问所有嵌套文档。
如果您知道需要在查询中检查第一个雇员的姓名,只需添加另一个根级别字段
FirstEmployeeName
并在该字段上运行查询。