Hibernate Search 5.5.3 - 按集合大小排序不再有效
Hibernate Search 5.5.3 - Sort by collection size no longer working
我一直在尝试从 Hibernate Search 5.5.2 迁移到 5.5.3,但我 运行 遇到了我的排序字段之一的问题。这是与 5.5.2 一起使用的代码(或者它可能不工作,只是没有抛出错误?)
public class CollectionCountBridge implements MetadataProvidingFieldBridge {
@Override
public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
builder.field(name, FieldType.INTEGER).sortable(true);
}
@Override
public void set(String name, Object object, Document document, LuceneOptions luceneOptions) {
if (object == null || (!(object instanceof Collection))) {
return;
}
Collection<?> coll = (Collection<?>) object;
int size = coll.size();
IntField field = new IntField(name, size, (luceneOptions.getStore() != Store.NO) ? Field.Store.YES : Field.Store.NO);
document.add(field);
}
}
...
@Field(analyze = Analyze.NO, norms = Norms.YES, index = Index.YES)
@FieldBridge(impl = CollectionCountBridge.class)
@IndexedEmbedded
@OneToMany
public Set<MyCollection> getMyCollection() {
return myCollection;
}
代码实质上将集合的大小存储为可排序字段。这是基于建议如果我需要通过桥定义可排序字段的文档,那么我必须实现 MetadataProvidingFieldBridge 以将其标记为可排序。然而,文档仅显示了字符串字段的示例,而我需要使用数字字段。 http://docs.jboss.org/hibernate/search/5.5/reference/en-US/html_single/#sortablefield-annotation
所以在升级到 5.5.3 之后,我开始收到如下错误:
org.hibernate.search.exception.SearchException: HSEARCH000307: Sort type INT is not compatible with string type of field 'myCollection'
我尝试了多种方式将字段添加到文档中,但似乎没有任何效果。我尝试过的一些事情:
luceneOptions.addNumericFieldToDocument(name, size, document);
document.add(new SortedNumericDocValuesField(name, size));
//this throws an error on index
java.lang.IllegalArgumentException: cannot change DocValues type from SORTED_NUMERIC to NUMERIC for field "myCollection"
public class CollectionCountBridge extends NumberBridge
所以,我的问题是,从 5.5.3 开始,通过桥向索引添加可排序数字字段的正确方法是什么?
看来你遇到了一个错误。对于像您这样的自定义网桥,我们无法正确检测数字编码类型。为此,我已提交 HSEARCH-2292。
作为变通方法,您可以在您的实体中创建一个瞬态 属性 来公开集合大小。对于这个 属性,您添加 @Field
和 @SortableField
,它们应该使用正确的类型将所需的字段添加到索引中。
其实不是bug。
您必须在文档中添加相应的 NumericDocValuesField 才能启用排序。我们将在未来改进它,但现在,这是你必须做的。
此外,我不建议您添加与默认字段同名的字段,您最好使用其他字段名称索引集合大小。
您的 FieldBridge 应如下所示:
public class CollectionCountBridge implements MetadataProvidingFieldBridge {
private static final String COUNT_SUFFIX = "_count";
@Override
public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
builder.field(name + COUNT_SUFFIX, FieldType.INTEGER).sortable(true);
}
@Override
public void set(String name, Object object, Document document, LuceneOptions luceneOptions) {
if (object == null || (!(object instanceof Collection))) {
return;
}
Collection<?> coll = (Collection<?>) object;
int size = coll.size();
luceneOptions.addNumericFieldToDocument(name + COUNT_SUFFIX, size, document);
document.add(new NumericDocValuesField(name + COUNT_SUFFIX, size.longValue()));
}
}
并且在排序时,使用新的 SortField( "myCollection_count", SortField.Type.LONG ) ).
我一直在尝试从 Hibernate Search 5.5.2 迁移到 5.5.3,但我 运行 遇到了我的排序字段之一的问题。这是与 5.5.2 一起使用的代码(或者它可能不工作,只是没有抛出错误?)
public class CollectionCountBridge implements MetadataProvidingFieldBridge {
@Override
public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
builder.field(name, FieldType.INTEGER).sortable(true);
}
@Override
public void set(String name, Object object, Document document, LuceneOptions luceneOptions) {
if (object == null || (!(object instanceof Collection))) {
return;
}
Collection<?> coll = (Collection<?>) object;
int size = coll.size();
IntField field = new IntField(name, size, (luceneOptions.getStore() != Store.NO) ? Field.Store.YES : Field.Store.NO);
document.add(field);
}
}
...
@Field(analyze = Analyze.NO, norms = Norms.YES, index = Index.YES)
@FieldBridge(impl = CollectionCountBridge.class)
@IndexedEmbedded
@OneToMany
public Set<MyCollection> getMyCollection() {
return myCollection;
}
代码实质上将集合的大小存储为可排序字段。这是基于建议如果我需要通过桥定义可排序字段的文档,那么我必须实现 MetadataProvidingFieldBridge 以将其标记为可排序。然而,文档仅显示了字符串字段的示例,而我需要使用数字字段。 http://docs.jboss.org/hibernate/search/5.5/reference/en-US/html_single/#sortablefield-annotation
所以在升级到 5.5.3 之后,我开始收到如下错误:
org.hibernate.search.exception.SearchException: HSEARCH000307: Sort type INT is not compatible with string type of field 'myCollection'
我尝试了多种方式将字段添加到文档中,但似乎没有任何效果。我尝试过的一些事情:
luceneOptions.addNumericFieldToDocument(name, size, document);
document.add(new SortedNumericDocValuesField(name, size));
//this throws an error on index
java.lang.IllegalArgumentException: cannot change DocValues type from SORTED_NUMERIC to NUMERIC for field "myCollection"
public class CollectionCountBridge extends NumberBridge
所以,我的问题是,从 5.5.3 开始,通过桥向索引添加可排序数字字段的正确方法是什么?
看来你遇到了一个错误。对于像您这样的自定义网桥,我们无法正确检测数字编码类型。为此,我已提交 HSEARCH-2292。
作为变通方法,您可以在您的实体中创建一个瞬态 属性 来公开集合大小。对于这个 属性,您添加 @Field
和 @SortableField
,它们应该使用正确的类型将所需的字段添加到索引中。
其实不是bug。
您必须在文档中添加相应的 NumericDocValuesField 才能启用排序。我们将在未来改进它,但现在,这是你必须做的。
此外,我不建议您添加与默认字段同名的字段,您最好使用其他字段名称索引集合大小。
您的 FieldBridge 应如下所示:
public class CollectionCountBridge implements MetadataProvidingFieldBridge {
private static final String COUNT_SUFFIX = "_count";
@Override
public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
builder.field(name + COUNT_SUFFIX, FieldType.INTEGER).sortable(true);
}
@Override
public void set(String name, Object object, Document document, LuceneOptions luceneOptions) {
if (object == null || (!(object instanceof Collection))) {
return;
}
Collection<?> coll = (Collection<?>) object;
int size = coll.size();
luceneOptions.addNumericFieldToDocument(name + COUNT_SUFFIX, size, document);
document.add(new NumericDocValuesField(name + COUNT_SUFFIX, size.longValue()));
}
}
并且在排序时,使用新的 SortField( "myCollection_count", SortField.Type.LONG ) ).