使用休眠搜索的自定义网桥时出错 [英] Error on using a custom bridge of hibernate-search

查看:81
本文介绍了使用休眠搜索的自定义网桥时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体:

@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(期望值= NUM​​ERIC).使用UninvertingReader或带有文档值的索引.

注意:我正在使用hibernate-search 5.10. 我想在用户界面上显示 contactType.name 名称,而不是数字. 了解更多详情

Note: I am using hibernate-search 5.10. I want to show contactType.name name on UI instead of number. For more detail

推荐答案

似乎我的原始建议在set()方法中缺少了一点,以便添加docvalues:

Seems my original suggestion was missing a bit in the set() method, in order to add the docvalues:


     @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);
        }
    }

最重要的是,如果需要将字段用于排序和投影,则建议声明两个字段.否则,投影将返回整数,这不是您想要的.

On top of that, if you need to use the field for both sort and projection, I would recommend declaring two fields. Otherwise the projection will return integers, which is not what you want.

因此,请执行以下操作:

So, do this:

@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",...);
...

这篇关于使用休眠搜索的自定义网桥时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆