休眠搜索子实体

时间:2018-07-02 12:07:10

标签: orm hibernate-mapping hibernate-search hibernate-query

我将三个类定义为:

1)类别:-

@Entity
@Table(name = "CATEGORY")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Indexed
public class Category {

@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES, store = Store.YES, analyzer = @Analyzer(definition = "ngram"))
private String categoryName;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "categoryId", referencedColumnName = "id")
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<SubCategory> subCategories;

private Long creationTime;

private Long updationTime;
}

2)SubCategory类:-

 @Entity
 @Table(name = "SUB_CATEGORY")
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Indexed
 public class SubCategory {


@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram1"))
private String subCategoryName;

@Field(index = Index.YES,store = Store.YES)
private Long categoryId;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "subCategoryId", referencedColumnName = "id")
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<Pages> pages;

private Long creationTime;
}

3)页面类:-

 @Entity
 @Table(name = "PAGES")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Indexed
public class Pages {

@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private String pageName;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private String pageDescription;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private Long subCategoryId;

private Long creationTime;
}

现在数据定义如下:-

   Category              SubCategory              Pages
   --------              ------------             -------
   Vehicle                Car                     BMW
   Electricals            MotorCycle              Hero
   ...........            ........                Audi
   ...........            ........                ...... 
   Lapzz                  Laptop                  ......
                                                  Dell

现在,我被困在获取将使用休眠搜索在所有三个类中进行搜索的查询(即,如果我搜索Lap *),我应该从Categories,Subcategories和Pages中获取结果,并且只有与查询匹配的行才不会类别的完整对象。

例如,当我搜索Lap *时,应该进入结果集类别中包含Lapzz的行,并在子类别中包含笔记本电脑的行。 请帮我找到解决方案。

1 个答案:

答案 0 :(得分:0)

据我所知,这应该做您想要的:

String searchTerms = ...;

QueryBuilder categoryQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Category.class ).get();
QueryBuilder subCategoryQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( SubCategory.class ).get();
QueryBuilder pagesQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Pages.class ).get();

Query categoryQuery = categoryQb.keyword()
    .onField( "categoryName" )
    .matching( searchTerms )
    .createQuery();
Query subCategoryQuery = subCategoryQb.keyword()
    .onField( "subCategoryName" )
    .matching( searchTerms )
    .createQuery();
Query pagesQuery = pagesQb.keyword()
    .onFields(
        "pageName",
        "pageDescription"
    )
    .matching( searchTerms )
    .createQuery();

Query luceneQuery = categoryQb.bool()
        .should( categoryQuery )
        .should( subCategoryQuery )
        .should( pagesQuery )
        .createQuery();

FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(
    luceneQuery,
    Category.class, SubCategory.class, Pages.class
);

List<?> results = fullTextQuery.getResultList();

在这里需要几个警告:

  • 由于您正在使用ngram过滤器,因此查询时可能需要使用其他分析器;参见this answer
  • 您在@Field上的Pages.subcategoryId注释非常可疑:分析数值没有意义。为此,将另一个实体的ID存储在Pages中是可疑的,您通常希望有一个类型为SubCategory的字段,并用@ManyToOne进行注释。
  • 如果您希望查询匹配描述中没有搜索词但包含名称或描述包含搜索词的页面的类别,则必须添加IndexedEmbedded并添加搜索查询的嵌入字段("pages.pageName""pages.pageDescription",...)。