Hibernate搜索@IndexEmbedded将集合合并到一个字段中

时间:2017-06-16 09:25:27

标签: lucene full-text-search hibernate-search

我的映射看起来像:

@Entity
@Table(name = "t_documents")
@Indexed(interceptor = DocumentIndexingInterceptor.class)
public class Document implements Serializable {
    @Id
    @GeneratedValue
    @DocumentId
    private Long id;

    @IndexedEmbedded(prefix = "sections.", indexNullAs = "null", 
      includePaths = {"body"})
    private List<Section> sections;

//...
}

@Entity
@Table(name = "t_sections")
@Indexed
public class Section implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @DocumentId
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ndocumentid")
    private Document document;

    @Field(name = "body", 
           analyze = Analyze.YES, 
           index = Index.YES, 
           store = Store.NO,
           norms = Norms.NO)
    @Column(name = "vbody")
    private String body;

//...
}

现在,如果我有一个实体文档,其中包含两个Section实体,如下所示: 第1节正文:“回答你自己的问题”;
第2节正文:“发表你的问题”;
*其他值并不重要。

当我在Luke sections.body 中查看索引实体文档时,看起来像:

answer your own question post your question

当我搜索包含句子“答案帖子”的文件时,它会找到这个特定的文件。这不是我想要的结果。我希望只有在单个体内找到我搜索到的字符串时才能找到此文档。

这甚至可能吗?如果没有,有没有办法实现我想要的。

1 个答案:

答案 0 :(得分:0)

这是集合@IndexedEmbedded的固有限制:集合的所有元素都合并在一起。

首先要问自己的问题是:你真的在寻找文件吗?如果您不希望不同部分中的两个单词匹配,则可能需要搜索部分。 如果是这种情况,您只需将查询更改为定位Section.class而不是Document.class

如果您还需要能够在Document中搜索字段,那么您可以反过来嵌入:在@IndexedEmbedded上放置Section.document },像这样:

@Entity
@Table(name = "t_documents")
@Indexed(interceptor = DocumentIndexingInterceptor.class)
public class Document implements Serializable {
    @Id
    @GeneratedValue
    @DocumentId
    private Long id;

    @ContainedIn // IMPORTANT: this will ensure that the "section" index is updated whenever a section is updated
    private List<Section> sections;

//...
}

@Entity
@Table(name = "t_sections")
@Indexed // TODO: if you need it, put an interceptor here, just as in Document?
public class Section implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @DocumentId
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ndocumentid")
    @IndexedEmbedded(indexNullAs = "null", includePaths = { /* LIST YOUR PATHS HERE */ })
    private Document document;

    @Field(name = "body", 
           analyze = Analyze.YES, 
           index = Index.YES, 
           store = Store.NO,
           norms = Norms.NO)
    @Column(name = "vbody")
    private String body;

//...
}