elasticsearch,Filter,Nested,elasticsearch" /> elasticsearch,Filter,Nested,elasticsearch" />

Filter Elasticsearch访问脚本筛选器内的嵌套数据(使用_source避免PropertyAccessException)

Filter Elasticsearch访问脚本筛选器内的嵌套数据(使用_source避免PropertyAccessException),filter,nested,elasticsearch,Filter,Nested,elasticsearch,我决定在这里发布一个解决方案,因为我上周花了太多时间在上面,希望它能帮助别人。我还需要回顾一下Elasticsearch专家们,你们这些家伙,以确保我理解了我在这里谈论的概念 我的情况很简单:我必须处理ES脚本过滤器中的嵌套对象。 考虑到我正在处理的应用程序的体系结构,我唯一可以操作它们的地方就是它的内部。这意味着我无法使用官方的ES Nester过滤器 这是我的映射,我更改了属性名称以获得经典书籍示例: mappings: { book: { properties: {

我决定在这里发布一个解决方案,因为我上周花了太多时间在上面,希望它能帮助别人。我还需要回顾一下Elasticsearch专家们,你们这些家伙,以确保我理解了我在这里谈论的概念

我的情况很简单:我必须处理ES脚本过滤器中的嵌套对象。 考虑到我正在处理的应用程序的体系结构,我唯一可以操作它们的地方就是它的内部。这意味着我无法使用官方的ES Nester过滤器

这是我的映射,我更改了属性名称以获得经典书籍示例:

mappings: {
    book: {
        properties: {
            id: {
                type: long
            }
            genre: {
                type: string
            }
            title: {
                type: string
            }
            reviews: {
                properties: {
                    id: {
                        type: long
                    }
                    bookId: {
                        type: long
                    }
                    text: {
                        type: string
                    }
                    note: {
                        type: long
                    }
                    author: {
                        type: string
                    }
                }
            }
            year: {
                type: long
            }
        }
    }
}
这意味着一本书可以有零篇或多篇评论。 一旦我的弹性搜索查询运行,假设我希望能够使用一个脚本过滤器来过滤结果,只保留最近的2年的MAX,最好的评论>14,在纽约时报的20刻度上。 我对一本最近的书不感兴趣,这本书有一个好的注释,不是《纽约时报》写的,或者是相反的

以下是我的过滤器->过滤器->脚本->脚本的内容:

Calendar calendar = Calendar.getInstance(); 
yearWanted = calendar.get(Calendar.YEAR) - 2; 
boolean yearTest = (doc['year'].?value >= yearWanted); 

boolean reviewTest = false; 
if (_source.reviews != null) {
    for (review : _source.reviews) {
        if (!reviewTest && review.author contains 'new york times' && review.note >= 14) {reviewTest = true;}
    }
}

return (yearTest && reviewTest);
它只在移除回车时起作用,但我想确定我假设的上述所有事情:

为索引中的每个文档播放脚本筛选器

-如果返回true,则迭代的文档将在返回的列表中

-如果返回false,则迭代的文档将不在返回的列表中

这意味着,如果要列出索引中的所有文档,脚本=return false;行得通

在脚本中始终使用小写字符串:ES存储所有字符串,如下所示

我说得对吗

最后的想法:

我想在我的for中使用休息,但MVEL似乎不可能

非常感谢Felix Hürlimann,他的文章帮助我了解了很多情况

感谢guyz的反馈:


祝你今天愉快

对于blog link+1,请小心屏蔽对_source属性的访问,如if _source.reviews!=null,否则您可能在生产中有一个PropertyAccessException!我更新了下面的脚本,因为首先使用的mvelempty关键字效率不高:我们与我的团队发现,该脚本在本地、预生产中运行良好,但在生产中没有运行。希望它能帮助。。。