休眠搜索子实体
Posted
技术标签:
【中文标题】休眠搜索子实体【英文标题】:Hiberate search for child entities 【发布时间】:2018-07-02 12:07:10 【问题描述】:我将三个类定义为:
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*)我应该从类别、子类别和页面中获取结果,并且只有与查询匹配的行不是Category 的完整对象。
例如,当我搜索 Lap* 时,我应该在结果集中获得类别中包含 Lapzz 的行和子类别中包含笔记本电脑的行。 请帮我找到这个解决方案。
【问题讨论】:
你说的“行”是什么意思?在您的结果中,您是否想要混合使用Category
、SubCategory
和 Pages
对象,具体取决于匹配的对象?或者您是否只想要 Page
对象,即使您的条件与某个类别匹配(在这种情况下,您将获得匹配类别的所有页面)?
我想要类别、子类别和页面的混合。假设我搜索一个查询,那么结果应该包含所有三个表数据的混合。
【参考方案1】:
据我所知,这应该做你想做的事:
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 answerPages.subcategoryId
上的 @Field
注释非常可疑:分析数值没有意义。就此而言,将另一个实体的 ID 存储在 Pages
中是可疑的,您通常希望拥有一个类型为 SubCategory
的字段,并使用 @ManyToOne
对其进行注释。
如果您希望查询匹配描述中没有搜索词但包含名称或描述中包含搜索词的页面的类别,则必须添加 IndexedEmbedded 并添加嵌入的字段("pages.pageName"
、"pages.pageDescription"
、...)添加到您的搜索查询中。
【讨论】:
感谢您的回答。我将合并所有这些更改。以上是关于休眠搜索子实体的主要内容,如果未能解决你的问题,请参考以下文章