Hibernate Search Elasticsearch后端嵌套对象过滤排序报错如何解决?
问题原因
你遇到的HSEARCH400604报错是因为用错了排序的filter功能:这个功能仅适用于嵌套(nested)结构的集合字段排序,作用是先过滤嵌套集合中符合条件的元素,再用符合条件的元素字段值做排序。你的vente是@ManyToOne单值关联,对应的@IndexedEmbedded默认是平铺式的对象结构,不是嵌套集合,所以不支持排序filter。
解决方案
你要实现的「文档有dateOfBirth就按它排序,无则按age/acte.signature排序」的需求,不需要用到排序filter,用以下两种方案都可以实现:
方案1:字段优先级排序(最简便,无需修改映射)
直接设置两个排序字段,给优先级更高的dateSignature字段配置缺失值处理规则即可:
case DATE_SIGNATURE: // 第一排序规则:优先按dateSignature排序 FieldSortOptionsStep dateSignatureSort = f.field(Depot_.VENTE + "." + Vente_.DATE_SIGNATURE) // 无dateSignature值的文档统一排在有值文档的后面,需要排前面就改为SortMissing.FIRST .missing().last(); // 第二排序规则:无dateSignature值的文档按acte.signature排序 FieldSortOptionsStep acteSignatureSort = f.field(Depot_.VENTE + "." + Vente_.ACTE + "." + Acte_.SIGNATURE); sortFieldOrderedList.add(dateSignatureSort); sortFieldOrderedList.add(acteSignatureSort); break;
该逻辑完全符合你的需求:所有有dateSignature值的文档会先按这个字段值排序,只有无该字段值的文档才会进入第二个字段的排序逻辑。
方案2:脚本排序(适合复杂逻辑扩展)
如果后续需要更复杂的排序判断规则,可以用Painless脚本排序实现:
case DATE_SIGNATURE: sortFieldOrderedList.add( f.script() .lang("painless") .source(""" if (doc.containsKey('vente.dateSignature') && !doc['vente.dateSignature'].empty) { return doc['vente.dateSignature'].value.toEpochMilli(); } else if (doc.containsKey('vente.acte.signature') && !doc['vente.acte.signature'].empty) { return doc['vente.acte.signature'].value.toEpochMilli(); } return Long.MAX_VALUE; """) ); break;
内容的提问来源于stack exchange,提问作者François F.
相关产品推荐
相关产品推荐

