使用 hibernate-search 的自定义桥时出错

2024-03-23

我有两个实体:

@Indexed
@Entity
@Table(name = "LK_CONTACT_TYPE")
public class ContactTypeEntity {
    @Id
    @Column(name = "ID")
    @DocumentId
    Integer id;

    @SortableField
    @Field(store = Store.YES, bridge = @FieldBridge(impl = ContactTypeComparator.class))
    @Column(name = "NAME")
    String name; 

    getter() .. setter()..
}



@Indexed
 @Entity
 @Table(name = "DIRECTORY")
 public class DirectoryEntity {
    ....
    @IndexedEmbedded(prefix = "contactType.", includePaths = {"id", "name"})
    @ManyToOne
    @JoinColumn(name = "CONTACT_TYPE")
    private ContactTypeEntity contactType;

    getter() ... setter()...
}

public class ContactTypeComparator implements MetadataProvidingFieldBridge, TwoWayStringBridge {

     @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        if ( value != null ) {
          int ordinal = getOrdinal(value.toString());
          luceneOptions.addNumericFieldToDocument(name, ordinal, document);
        }
    }

    @Override
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
        builder.field(name, FieldType.INTEGER).sortable(true);
    }

    private int getOrdinal(ContactType value) {
        switch( value ) {
          case PBX: return 0;
          case TEL: return 1;
          case GSM: return 2;
          case FAX: return 3;
          default: return 4;
        }
    }


    @Override
    public Object get(String name, Document document) {
    return document.get( name );
   }

    @Override
    public String objectToString(Object object) {
    return object.toString();
   }
}

和查询部分:

...
query.setSort(queryBuilder.sort().byScore().andByField("contactType.name").createSort());
query.setProjection(... , "contactType.name",...);
...

我收到以下错误:java.lang.IllegalStateException:字段“contactType.name”的意外文档值类型为 NONE(预期=NUMERIC)。使用 UninvertingReader 或带有文档值的索引。

注意:我使用的是 hibernate-search 5.10。我想展示contactType.name用户界面上的名称而不是号码。 了解更多详情 https://stackoverflow.com/questions/59658935/how-to-boost-hibernate-search-query-with-field-values/59721290?noredirect=1#comment105613864_59721290


似乎我原来的建议有点缺失set()方法,为了添加文档值:


     @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        if ( value != null ) {
          int ordinal = getOrdinal(value.toString());
          luceneOptions.addNumericFieldToDocument(name, ordinal, document);
          // ADD THIS
          luceneOptions.addNumericDocValuesFieldToDocument(name, ordinal, document);
        }
    }

最重要的是,如果您需要使用该字段进行排序和投影,我建议声明two字段。否则投影将返回整数,这不是您想要的。

所以,这样做:

@Indexed
@Entity
@Table(name = "LK_CONTACT_TYPE")
public class ContactTypeEntity {
    @Id
    @Column(name = "ID")
    @DocumentId
    Integer id;

    @SortableField
    // CHANGE THESE TWO LINES
    @Field(store = Store.YES)
    @Field(name = "name_sort", bridge = @FieldBridge(impl = ContactTypeComparator.class))
    @Column(name = "NAME")
    String name; 

    getter() .. setter()..
}



@Indexed
 @Entity
 @Table(name = "DIRECTORY")
 public class DirectoryEntity {
    ....
    // CHANGE THIS LINE
    @IndexedEmbedded(prefix = "contactType.", includePaths = {"id", "name", "name_sort"})
    @ManyToOne
    @JoinColumn(name = "CONTACT_TYPE")
    private ContactTypeEntity contactType;

    getter() ... setter()...
}

public class ContactTypeComparator implements MetadataProvidingFieldBridge, TwoWayStringBridge {

     @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        if ( value != null ) {
          int ordinal = getOrdinal(value.toString());
          luceneOptions.addNumericFieldToDocument(name, ordinal, document);
          // ADD THIS LINE
          luceneOptions.addNumericDocValuesFieldToDocument(name, ordinal, document);
        }
    }

    @Override
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
        builder.field(name, FieldType.INTEGER).sortable(true);
    }

    private int getOrdinal(ContactType value) {
        switch( value ) {
          case PBX: return 0;
          case TEL: return 1;
          case GSM: return 2;
          case FAX: return 3;
          default: return 4;
        }
    }


    @Override
    public Object get(String name, Document document) {
    return document.get( name );
   }

    @Override
    public String objectToString(Object object) {
    return object.toString();
   }
}

然后像这样查询:

...
query.setSort(queryBuilder.sort().byScore().andByField("contactType.name_sort").createSort());
query.setProjection(... , "contactType.name",...);
...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 hibernate-search 的自定义桥时出错 的相关文章

随机推荐