我正在使用elasticSearch查找系列中的下一集。我这样做的方法是首先过滤比上一集更高season
或更高episode
的剧集,然后按升序排序season
和episode
,以及将我的结果限制为1:
...
FilterBuilder sameSeriesFilter = termsFilter("tvShowId", previousEpisode.getTvShowId());
FilterBuilder greaterEpisodeFilter = rangeFilter("episode").gt(previousEpisode.getEpisode());
FilterBuilder greaterSeasonFilter = rangeFilter("season").gt(previousEpisode.getSeason());
List<Sort.Field> sortFields = Arrays.asList(new Sort.Field("season", Sort.Order.ASC),new Sort.Field("episode", Sort.Order.ASC));
Sort episodeSort = new Sort(sortFields);
AndFilterBuilder filter = FilterBuilders.andFilter(
sameSeriesFilter,
orFilter(
greaterEpisodeFilter,
greaterSeasonFilter
)
);
String query = filter.toString(); //here for debugging purposes
return client.getItems(GetItems
.<Asset>newBuilder()
.index(index)
.filter(filter)
.sort(episodeSort)
.page(1,1)
.type(ASSET)
.tClass(Asset.class)
.build()
);
}).map(assetHitList ->
assetHitList.getHits().isEmpty() ? null : assetHitList.getHits().get(0)) ;
}
在运行时将过滤器提取为字符串会给出以下查询:
{
"and" : {
"filters" : [ {
"terms" : {
"tvShowId" : [ "breaking-bad" ]
}
},{
"or" : {
"filters" : [ {
"range" : {
"episode" : {
"from" : 1,
"to" : null,
"include_lower" : false,
"include_upper" : true
}
}
}, {
"range" : {
"season" : {
"from" : 2,
"to" : null,
"include_lower" : false,
"include_upper" : true
}
}
} ]
}
} ]
}
}
令人困惑的结果是:
{
"assetId" : "breaking-bad-s01-e1_foobar",
"tvShowId" : "breaking-bad"
"episode" : "1",
"season" : "1",
"originalTitle" : "Dummy breaking-bad-s01-e1_foobar",
}
(为简洁起见,删除了一些字段)
请注意,结果中的episode
和season
都是1,即使过滤器指定(我认为)其中一个必须分别高于2和1。
我也试图反转排序,然后排序降序,这导致了一个完全不同的系列剧集,所以似乎sameSeriesFilter
也没有应用,但排序似乎有效!
更新: 忘了提,这是ES的第1.7节。
我已经设法让它运转起来,但一些神秘的事情正在发生。 一时兴起,我添加了一个空的matchAll查询,它应该什么也不做,但由于某种原因使一切正常。我的过滤器现在正确应用。 ES应该像这样工作吗?如果是这样,为什么? 新的和有效的代码:
return client.getItems(GetItems
.<Asset>newBuilder()
.index(index)
.matchAllQuery() //<--this made it work!?!
.filter(filter)
.sort(episodeSort)
.page(1,1)
.type(ASSET)
.tClass(Asset.class)
.build()
);