使用AnalyzerDiscriminator进行Hibernate搜索-仅在创建实体时调用Analyzer



你能帮我吗?

我正在实现Hibernate搜索,以在本地化网站上检索全球搜索结果(葡萄牙语和英语内容)

为此,我遵循了Hibernate Search文档中指示的步骤:http://docs.jboss.org/hibernate/search/4.5/reference/en-US/html_single/#d0e4141

根据本文档中的说明,除了实体本身的特定配置外,我还实现了一个"LanguageDiscriminator"类。

因为我没有得到我期望的结果(例如,我的实体存储了文本"Capuchinho",但当我搜索"capucho"时,我没有命中),我决定尝试调试执行,并尝试了解我配置的分析器是否正在使用。

在数据库中为实体创建新记录时,我可以看到调用了"LanguageDifferentiator"中的"getAnalyzerDefinitionName()"方法。太棒了但当我执行搜索时,不会发生同样的情况。有人能解释一下为什么吗?

我将在下面发布我的代码的关键部分。非常感谢您的反馈!

这是我想索引的一个实体

@Entity
@Table(name="NEWS_HEADER")
@Indexed
@AnalyzerDefs({
@AnalyzerDef(name = "en",
tokenizer = @TokenizerDef(factory =     StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, 
params = {@Parameter(name="language", value="English")}
)
}
),
@AnalyzerDef(name = "pt",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, 
params = {@Parameter(name="language", value="Portuguese")}
)
}
)
})
public class NewsHeader implements Serializable {
static final long serialVersionUID = 20140301L;
private int         id;
private String          articleHeader;
private String          language;
private Set<NewsParagraph>  paragraphs = new HashSet<NewsParagraph>();
/**
* @return the id
*/
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.AUTO)
@DocumentId
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return the articleHeader
*/
@Column(name="ARTICLE_HEADER")
@Field(index=Index.YES, store=Store.NO)
public String getArticleHeader() {
return articleHeader;
}
/**
* @param articleHeader the articleHeader to set
*/
public void setArticleHeader(String articleHeader) {
this.articleHeader = articleHeader;
}
/**
* @return the language
*/
@Column(name="LANGUAGE")
@Field
@AnalyzerDiscriminator(impl=LanguageDiscriminator.class)
public String getLanguage() {
return language;
}
...
}

这是我的语言鉴别器类

public class LanguageDiscriminator implements Discriminator {
@Override
public String getAnalyzerDefinitionName(Object value, Object entity, String field) {
String result = null;
if (value != null) {
result = (String) value;
}
return result;
}
}

这是我的SearchDAO 中的搜索方法

public List<NewsHeader> searchParagraph(String patternStr) {
Session session = null;
Transaction tx;
List<NewsHeader> result = null;
try {
session = sessionFactory.getCurrentSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
tx = fullTextSession.beginTransaction();
// Create native Lucene query using the query DSL
QueryBuilder queryBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(NewsHeader.class).get();
org.apache.lucene.search.Query luceneSearchQuery = queryBuilder
.keyword()
.onFields("articleHeader", "paragraphs.content")
.matching(patternStr)
.createQuery();
// Wrap Lucene query in a org.hibernate.Query
org.hibernate.Query hibernateQuery = 
fullTextSession.createFullTextQuery(luceneSearchQuery, NewsHeader.class, NewsParagraph.class);
// Execute search
result = hibernateQuery.list();
} catch (Exception xcp) {
logger.error(xcp);
} finally {
if ((session != null) && (session.isOpen())) {
session.close();
}
}
return result;
}
When creating a new record for the entity in the database, I can see that the "getAnalyzerDefinitionName()" method from the "LanguageDiscriminator" gets called. Great. But the same does not happen when I execute a search. Can anyone explain me why?

分析器的选择取决于给定实体的状态,在您的情况下NewsHeader。您正在索引期间处理实体实例。在查询时,您没有可开始的实体,而是在搜索它们。Hibernate Search会为您的查询选择哪个分析器?

也就是说,我认为DSL有一个缺点。它不允许显式指定类的分析器。有ignoreAnalyzer,但这不是您想要的。我想你可以在搜索问题跟踪器中创建一个功能请求-https://hibernate.atlassian.net/browse/HSEARCH.

同时,您可以使用原生Lucene查询API构建查询。但是,您需要知道查询的目标语言(例如,通过登录用户的首选语言或其他语言)。这将取决于您的用例。这可能是你一开始就看错了功能。

最新更新