我有以下2个实体定义。从Attribute到AttributeValue的关系是一对多。我想按指定的属性类别搜索属性实体并返回所有 具有至少一个与其相关联的属性值的匹配属性实体。
我尝试过的事情:
我尝试过一种幼稚的方法,首先搜索与指定属性类别匹配的所有属性,然后针对每个此类属性,按属性搜索属性值,然后返回所有匹配的实体。这样,我可以确定一个属性是否至少具有一个与之关联的属性值。不过,这种方法相当慢。
问题:
在休眠搜索中是否有更好的方法? (最好是在搜索属性之后,我已经返回了所有属性值计数信息。)我已经阅读了最新的休眠搜索官方文档中的 Embedded and associated objects 部分,但无法查看有一个明确的方法。任何帮助表示赞赏。
public class Attribute {
@Id
@DocumentId
@Column(name = "ID")
private Long id;
@Field
@Column(name = "ATTRIBUTE_NAME", unique = true, nullable = false)
private String attributeName;
@Field
@FieldBridge(impl = EnumBridge.class)
@Enumerated(EnumType.STRING)
@Column(name = "ATTRIBUTE_CATEGORY", nullable = false)
private AttributeCategory attributeCategory;
@IndexedEmbedded(includePaths = {"id"})
@OneToMany(fetch = FetchType.LAZY, mappedBy = "attribute", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<AttributeValue> attributeValues = new HashSet<>(); }
public class AttributeValue {
@Id
@DocumentId
@Column(name = "ID")
private Long id;
@Field
@Column(name = "ATTRIBUTE_VALUE_NAME")
private String attributeValueName;
@IndexedEmbedded(includePaths = {"id", "attributeName"})
@ManyToOne
@JoinColumn(name = "ATTRIBUTE_ID")
private Attribute attribute; }
答案 0 :(得分:0)
假设所有AttributeValue
都有一个ID,您可以尝试执行以下操作:
AttributeCategory expectedCategory = ...;
QueryBuilder qb = ...;
Query luceneQuery = qb.bool()
.must( qb.keyword().onField( "attributeCategory" )
.matching( expectedCategory ).createQuery() )
.must( qb.keyword().wildcard().onField( "attributeValues.id" )
.matching( "*" ).createQuery() )
.createQuery();
FullTextQuery query = Search.getSearchEntityManager( entityManager )
.createFullTextQuery( luceneQuery, Attribute.class );
query.setMaxResults( 20 );
List<Attribute> hits = query.getResultList();
在Hibernate Search 6(处于Beta版)中,使用exists
predicate会更直观(可能更有效)。但这需要您更改大多数代码,因为API是不同的:
AttributeCategory expectedCategory = ...;
List<Attribute> hits = Search.session( entityManager )
.search( Attribute.class )
.where( f -> f.bool()
.must( f.match().field( "attributeCategory" )
.matching( expectedCategory ) )
.must( f.exists().field( "attributeValue" ) ) )
.fetchHits( 20 );