将相同的分析器应用于查询和字段
Applying the same Analyzer to Queries and Fields
我正在尝试为我的 API 后端构建一个基本搜索。用户传递任意查询并且后端应该 return 结果(很明显)。我更喜欢使用本地索引和 Elasticsearch 的解决方案。
在我的实体上,我定义了一个这样的分析器:
@AnalyzerDef(name = "ngram",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class,
params = {
@Parameter(name = "minGramSize", value = "2"),
@Parameter(name = "maxGramSize", value = "3") } )
}
)
对于查询,我尝试了以下方法:
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(this.entityManager);
Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");
QueryParser queryParser = new MultiFieldQueryParser(ALL_FIELDS, analyzer);
queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
org.apache.lucene.search.Query query = queryParser.parse(queryString);
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, MyEntity.class);
List<MyEntity> result = persistenceQuery.getResultList();
据我了解,我需要为查询提供分析器,以便搜索查询为 "ngram-tokenized" 并找到匹配项。之前,我使用 SimpleAnalyzer,结果,搜索只匹配完整的单词,我认为这支持我的理论(抱歉,我还在学习这个)。
上面的代码给我一个 NullPointerException:
java.lang.NullPointerException: null
at org.hibernate.search.engine.impl.ImmutableSearchFactory.getAnalyzer(ImmutableSearchFactory.java:370) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
at org.hibernate.search.engine.impl.MutableSearchFactory.getAnalyzer(MutableSearchFactory.java:203) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
at org.hibernate.search.impl.SearchFactoryImpl.getAnalyzer(SearchFactoryImpl.java:50) ~[hibernate-search-orm-5.11.1.Final.jar:5.11.1.Final]
行
Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");
使用 Elasticsearch 集成时,您无法从 Hibernate Search 检索分析器,因为在那种情况下,本地没有分析器:分析器仅存在于 Elasticsearch 集群中的远程。
如果您只需要查询语法的一个子集,请尝试 "simple query string" query:它是一个可以使用 DSL 构建的查询(因此它可以与 Lucene 和 Elasticsearch 一起工作)并且提供最常见的特征(布尔查询、模糊性、短语……)。例如:
Query luceneQuery = queryBuilder.simpleQueryString()
.onFields("name", "history", "description")
.matching("war + (peace | harmony)")
.createQuery();
语法有点不同,但只是因为它针对最终用户并试图更简单。
编辑:如果简单的查询字符串不是一个选项,您可以手动创建一个分析器:即使在使用 Elasticsearch 集成时这也应该有效。
org.apache.lucene.analysis.custom.CustomAnalyzer#builder()
应该是一个很好的起点。 class 的 javadoc 中有几个示例。
确保只创建一次分析器并将其存储在某个地方,例如在静态常量中:创建分析器可能成本很高。
我正在尝试为我的 API 后端构建一个基本搜索。用户传递任意查询并且后端应该 return 结果(很明显)。我更喜欢使用本地索引和 Elasticsearch 的解决方案。
在我的实体上,我定义了一个这样的分析器:
@AnalyzerDef(name = "ngram",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class ),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class),
@TokenFilterDef(factory = NGramFilterFactory.class,
params = {
@Parameter(name = "minGramSize", value = "2"),
@Parameter(name = "maxGramSize", value = "3") } )
}
)
对于查询,我尝试了以下方法:
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(this.entityManager);
Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");
QueryParser queryParser = new MultiFieldQueryParser(ALL_FIELDS, analyzer);
queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);
org.apache.lucene.search.Query query = queryParser.parse(queryString);
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, MyEntity.class);
List<MyEntity> result = persistenceQuery.getResultList();
据我了解,我需要为查询提供分析器,以便搜索查询为 "ngram-tokenized" 并找到匹配项。之前,我使用 SimpleAnalyzer,结果,搜索只匹配完整的单词,我认为这支持我的理论(抱歉,我还在学习这个)。
上面的代码给我一个 NullPointerException:
java.lang.NullPointerException: null
at org.hibernate.search.engine.impl.ImmutableSearchFactory.getAnalyzer(ImmutableSearchFactory.java:370) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
at org.hibernate.search.engine.impl.MutableSearchFactory.getAnalyzer(MutableSearchFactory.java:203) ~[hibernate-search-engine-5.11.1.Final.jar:5.11.1.Final]
at org.hibernate.search.impl.SearchFactoryImpl.getAnalyzer(SearchFactoryImpl.java:50) ~[hibernate-search-orm-5.11.1.Final.jar:5.11.1.Final]
行
Analyzer analyzer = fullTextEntityManager.getSearchFactory().getAnalyzer("ngram");
使用 Elasticsearch 集成时,您无法从 Hibernate Search 检索分析器,因为在那种情况下,本地没有分析器:分析器仅存在于 Elasticsearch 集群中的远程。
如果您只需要查询语法的一个子集,请尝试 "simple query string" query:它是一个可以使用 DSL 构建的查询(因此它可以与 Lucene 和 Elasticsearch 一起工作)并且提供最常见的特征(布尔查询、模糊性、短语……)。例如:
Query luceneQuery = queryBuilder.simpleQueryString()
.onFields("name", "history", "description")
.matching("war + (peace | harmony)")
.createQuery();
语法有点不同,但只是因为它针对最终用户并试图更简单。
编辑:如果简单的查询字符串不是一个选项,您可以手动创建一个分析器:即使在使用 Elasticsearch 集成时这也应该有效。
org.apache.lucene.analysis.custom.CustomAnalyzer#builder()
应该是一个很好的起点。 class 的 javadoc 中有几个示例。
确保只创建一次分析器并将其存储在某个地方,例如在静态常量中:创建分析器可能成本很高。