使用休眠搜索的自定义网桥时出错

问题描述 投票:1回答:1

我有两个实体:

@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'(expected = NUM​​ERIC)的文档类型意外为NONE。使用UninvertingReader或带有docvalue的索引。

注意:我正在使用hibernate-search 5.10。我想在UI上显示contactType.name名称而不是数字。For more detail

hibernate-search
1个回答
1
投票

[似乎我的原始建议在set()方法中缺少了一点,以便添加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);
        }
    }

最重要的是,如果需要将字段用于排序和投影,我建议声明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",...);
...
© www.soinside.com 2019 - 2024. All rights reserved.