Hibernate-search 按数字列表搜索
Hibernate-search search by list of numbers
我在 Hibernate 搜索中工作,Java 应用程序的实体具有索引的数字字段:
@Field
@NumericField
private Long orgId;
我想获取与此 属性 的 Long 值列表相匹配的实体列表。我使用 "simpleQueryString" 因为它允许使用 "OR" 逻辑与 char |对于几个 objective 值。我有这样的东西:
queryBuilder.simpleQueryString().onField("orgId").matching("1|3|8").createQuery()
在 运行 mi 申请后我得到:
指定的查询“+(orgId:1 orgId:3 orgId:8)”包含一个基于字符串的子查询,该子查询以数字编码字段为目标 'orgId'.检查您的查询或尝试限制目标实体。
所以,有人能告诉我这段代码有什么问题吗?还有其他方法可以满足我的需要吗?
=================================
更新 1:
yrodiere' 回答解决了这个问题,但我还有一个疑问,我想验证实体是否匹配其他字段,我知道我可以使用 BooleanJuntion,但我需要混合 "must" 和 "should"用法对吗?即:
BooleanJunction<?> bool = queryBuilder.bool();
for (Integer orgId: orgIds) {
bool.should( queryBuilder.keyword().onField("orgId").matching(orgId).createQuery() );
}
bool.must(queryBuilder.keyword().onField("name").matching("anyName").createQuery() );
然后,我正在验证实体必须匹配 "name" 并且它们还匹配给定的 orgId 之一,我说得对吗?
如错误信息所述:
The specified query [...] contains a string based sub query which targets the numeric encoded field(s) 'orgId'.
simpleQueryString
只能用于定位文本字段。不支持数字字段。
如果您的字符串是通过编程方式生成的,并且您有一个整数列表,那么您需要执行以下操作:
List<Integer> orgIds = Arrays.asList(1, 3, 8);
BooleanJunction<?> bool = queryBuilder.bool();
for (Integer orgId: orgIds) {
bool.should( queryBuilder.keyword().onField("orgId").matching(orgId).createQuery() );
}
LuceneQuery query = bool.createQuery();
query
将匹配 orgId
字段包含 1
、3
或 8
.
的文档
见https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#_combining_queries
编辑:如果您需要额外的子句,我建议不要在同一个布尔连接中混合使用 must 和 should,而是嵌套布尔连接。
例如:
BooleanJunction<?> boolForOrgIds = queryBuilder.bool();
for (Integer orgId: orgIds) {
boolForOrgIds.should(queryBuilder.keyword().onField("orgId").matching(orgId).createQuery());
}
BooleanJunction<?> boolForWholeQuery = queryBuilder.bool();
boolForWholeQuery.must(boolForOrgIds.createQuery());
boolForWholeQuery.must(queryBuilder.keyword().onField("name").matching("anyName").createQuery());
// and add as many "must" as you need
LuceneQuery query = boolForWholeQuery.createQuery();
从技术上讲,您 可以 混合使用 'must' 和 'should',但效果不会如您所愿:'should' 子句将变为可选的,只会在匹配时提高文档的分数。所以,这里不是你需要的。
我在 Hibernate 搜索中工作,Java 应用程序的实体具有索引的数字字段:
@Field
@NumericField
private Long orgId;
我想获取与此 属性 的 Long 值列表相匹配的实体列表。我使用 "simpleQueryString" 因为它允许使用 "OR" 逻辑与 char |对于几个 objective 值。我有这样的东西:
queryBuilder.simpleQueryString().onField("orgId").matching("1|3|8").createQuery()
在 运行 mi 申请后我得到:
指定的查询“+(orgId:1 orgId:3 orgId:8)”包含一个基于字符串的子查询,该子查询以数字编码字段为目标 'orgId'.检查您的查询或尝试限制目标实体。
所以,有人能告诉我这段代码有什么问题吗?还有其他方法可以满足我的需要吗?
================================= 更新 1:
yrodiere' 回答解决了这个问题,但我还有一个疑问,我想验证实体是否匹配其他字段,我知道我可以使用 BooleanJuntion,但我需要混合 "must" 和 "should"用法对吗?即:
BooleanJunction<?> bool = queryBuilder.bool();
for (Integer orgId: orgIds) {
bool.should( queryBuilder.keyword().onField("orgId").matching(orgId).createQuery() );
}
bool.must(queryBuilder.keyword().onField("name").matching("anyName").createQuery() );
然后,我正在验证实体必须匹配 "name" 并且它们还匹配给定的 orgId 之一,我说得对吗?
如错误信息所述:
The specified query [...] contains a string based sub query which targets the numeric encoded field(s) 'orgId'.
simpleQueryString
只能用于定位文本字段。不支持数字字段。
如果您的字符串是通过编程方式生成的,并且您有一个整数列表,那么您需要执行以下操作:
List<Integer> orgIds = Arrays.asList(1, 3, 8);
BooleanJunction<?> bool = queryBuilder.bool();
for (Integer orgId: orgIds) {
bool.should( queryBuilder.keyword().onField("orgId").matching(orgId).createQuery() );
}
LuceneQuery query = bool.createQuery();
query
将匹配 orgId
字段包含 1
、3
或 8
.
见https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#_combining_queries
编辑:如果您需要额外的子句,我建议不要在同一个布尔连接中混合使用 must 和 should,而是嵌套布尔连接。
例如:
BooleanJunction<?> boolForOrgIds = queryBuilder.bool();
for (Integer orgId: orgIds) {
boolForOrgIds.should(queryBuilder.keyword().onField("orgId").matching(orgId).createQuery());
}
BooleanJunction<?> boolForWholeQuery = queryBuilder.bool();
boolForWholeQuery.must(boolForOrgIds.createQuery());
boolForWholeQuery.must(queryBuilder.keyword().onField("name").matching("anyName").createQuery());
// and add as many "must" as you need
LuceneQuery query = boolForWholeQuery.createQuery();
从技术上讲,您 可以 混合使用 'must' 和 'should',但效果不会如您所愿:'should' 子句将变为可选的,只会在匹配时提高文档的分数。所以,这里不是你需要的。