通过hibernate搜索我有lucene的索引问题:
产品领域:
@Entity
@Table(name="T_PRD")
@Indexed
public class Product implements java.io.Serializable {
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "T_TMPL_ATTR_VALUE", joinColumns = { @JoinColumn(name = "EntityId", unique=false) }, inverseJoinColumns = { @JoinColumn(name = "AttrId", unique=false) }, uniqueConstraints=@UniqueConstraint(columnNames={"EntityId","AttrId"}))
@IndexedEmbedded(prefix="prd.ca.")
private Set<TemplateAttribute> customTemplateAttributes;
}
TemplateAttribute Domain:
@Entity
@Table(name = "T_TMPL_ATTRS")
public class TemplateAttribute implements java.io.Serializable {
@OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, mappedBy = "templateAttribute")
@IndexedEmbedded
private Set<TemplateAttributeValue> templateAttrValues = new HashSet<TemplateAttributeValue>(0);
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "T_TMPL_ATTR_VALUE", joinColumns = { @JoinColumn(name = "AttrId", unique=false) }, inverseJoinColumns = { @JoinColumn(name = "EntityId", unique=false)}, uniqueConstraints=@UniqueConstraint(columnNames={"EntityId","AttrId"}))
@ContainedIn
private Set<Product> product;
@Column(name = "DefaultValue")
private String defaultValue;
}
TemplateAttributeValue域(桥接表,其中 attrValue 字段包含产品特定值):
@Entity
@Table(name = "T_TMPL_ATTR_VALUE")
public class TemplateAttributeValue implements java.io.Serializable {
@DocumentId(name="id")
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "entityId", column = @Column(name = "EntityId", nullable = false)),
@AttributeOverride(name = "attrId", column = @Column(name = "AttrId", nullable = false)) })
@FieldBridge(impl = TemplateAttributeCompositeKeyBridge.class)
public TemplateAttributeValueId getId() {
return this.id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "AttrId", nullable = false, insertable = false, updatable = false)
@ContainedIn
public TemplateAttribute getTemplateAttribute() {
return this.templateAttribute;
}
@Column(name = "AttrValue")
@Field(index = Index.YES, analyze = Analyze.YES, norms = Norms.NO, store = Store.NO)
public String getAttrValue() {
return this.attrValue==null?"":this.attrValue;
}
}
我打电话给doIndex方法如下:
private void doIndex() throws InterruptedException {
Session session = getSessionFactory().openSession();
session.enableFilter("onlyProductTemplate");
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
fullTextSession.close();
}
因此,让我们假设以下数据为例:
Product:
ID | Name
----------
1 | Prd1
2 | Prd2
3 | Prd3
Template Attribute:
AttrId | DefaultValue
---------------------
1 | Template1
2 | Template2
Template Attribute Value:
AttrId | EntityId | AttrValue
-----------------------------
1 | 1 | Template1
2 | 1 | Template2_modified
1 | 2 | Template1Updated
1 | 2 | Template2
1 | 3 | Template1
2 | 3 | Template2_newValue
因此,当我为产品实体创建索引时,每个产品都会生成模板属性值中定义的索引所有AttrValue 。
因此,当特定产品的搜索具有某些匹配的任何模板属性值时,它将返回列表中的所有产品。
那么如何在hibernate搜索中解决这个问题。
答案 0 :(得分:0)
我通过实施StringBridge
得到了解决方案,如下所示:
@Override
public String objectToString(Object value) {
if(value != null) {
String templateType = null;
if(value instanceof Set) {
StringBuilder strBuild = new StringBuilder();
Set<TemplateAttribute> setOfTempAttr = (Set<TemplateAttribute>) value;
for(TemplateAttribute tempValue : setOfTempAttr) {
int productID = tempValue.getProduct().getProductId();
Set<TemplateAttributeValue> setOfTempAttrValues = tempValue.getTemplateAttrValues();
for (TemplateAttributeValue taValue : setOfTempAttrValues) {
int entityID = taValue.getId().getEntityId();
if(entityID == productID) {
strBuild.append(" " + taValue.getAttrValue());
}
}
}
return strBuild.toString();
} else if(value instanceof String) {
templateType = (String) value;
}
return templateType;
}
return null;
}
意味着我们需要忽略要为其不属于的产品编制索引的attrValue 。再一次更改删除@ indexedEmbedded / @ ContainedIn注释并定义如下:
@Field(index = Index.YES, analyze = Analyze.YES, norms = Norms.NO, store = Store.NO)
@FieldBridge(impl = TemplateAttributeValueProductFieldBridge.class)
private Set<TemplateAttribute> customTemplateAttributes;