带有 ORM id 子查询的休眠 FullTextEntityManager 查询未能触发
hibernate FullTextEntityManager query with ORM id subquery failing to fire
我有一个全文查询,根据上一个问题的建议,我使用 Id 查询进行了过滤。由于某种原因,查询未能触发(我确定它之前触发过但是......)任何人都可以看到为什么吗?
Class<?> entityClass = entityType.getJavaType();
List<String> fields = buildFields(entityType.getProperties());
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
SearchFactory searchFactory = fullTextEntityManager.getSearchFactory();
QueryContextBuilder queryContextBuilder = searchFactory.buildQueryBuilder();
QueryBuilder queryBuilder = queryContextBuilder.forEntity(entityClass).get();
CriteriaBuilder idBuilder = m_storage.getCriteriaBuilder();
CriteriaQuery idQuery = idBuilder.createQuery(entityClass);
Root from = idQuery.from(entityClass);
idQuery.select(from.get("OID"));
Subquery<Long> subquery = idQuery.subquery(Long.class);
Root dateSQ = subquery.from(entityClass);
subquery.select(idBuilder.max(dateSQ.get("modDateTime")));
subquery.groupBy(dateSQ.get("surname"));
idQuery.where(idBuilder.in(from.get("modDateTime")).value(subquery));
TypedQuery typedQuery = m_storage.createQuery(idQuery);
List<Long> ids = typedQuery.getResultList();
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.must(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
SearchOption searchOption = uriInfo.getSearchOption();
Query query = queryBuilder.bool()
.must(processSearchExpression(searchOption.getSearchExpression(), queryBuilder,
fields.toArray(new String[fields.size()]))).filteredBy(idJunction.createQuery())
.createQuery();
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, entityClass);
return fullTextQuery;
//fullTextQuery fails to run
如果我删除过滤器等
query = queryBuilder.bool()
.must(processSearchExpression(searchOption.getSearchExpression(), queryBuilder,
fields.toArray(new String[fields.size()])))
.createQuery();
查询运行但显然没有按 ID 过滤。过滤器中有id。当我将 showSQL 设置为 true 时,如果我没有过滤器,我会看到一个查询,但是当我有过滤器时,我没有得到显示的查询(但没有抛出错误)
我似乎找不到任何问题?!
我不确定你说的 "the query doesn't fire" 是什么意思:
- 如果你调用
typedQuery.getResultList();
,肯定执行了一个查询。
- Hibernate 搜索查询不使用 SQL,因此 "setting a showSQL to true" 无济于事。您需要使用与 trace Hibernate Search queries.
不同的选项
无论如何,我假设您的问题是查询没有 return 命中?这是您编写查询的方式的问题。你写了这个:
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.must(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
... 表示 "the field 'recId' must have every single one of these id values".
而不是 "must",您应该使用 "should":
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.should(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
... 表示 "the field 'recId' must have at least one of these id values".
我有一个全文查询,根据上一个问题的建议,我使用 Id 查询进行了过滤。由于某种原因,查询未能触发(我确定它之前触发过但是......)任何人都可以看到为什么吗?
Class<?> entityClass = entityType.getJavaType();
List<String> fields = buildFields(entityType.getProperties());
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
SearchFactory searchFactory = fullTextEntityManager.getSearchFactory();
QueryContextBuilder queryContextBuilder = searchFactory.buildQueryBuilder();
QueryBuilder queryBuilder = queryContextBuilder.forEntity(entityClass).get();
CriteriaBuilder idBuilder = m_storage.getCriteriaBuilder();
CriteriaQuery idQuery = idBuilder.createQuery(entityClass);
Root from = idQuery.from(entityClass);
idQuery.select(from.get("OID"));
Subquery<Long> subquery = idQuery.subquery(Long.class);
Root dateSQ = subquery.from(entityClass);
subquery.select(idBuilder.max(dateSQ.get("modDateTime")));
subquery.groupBy(dateSQ.get("surname"));
idQuery.where(idBuilder.in(from.get("modDateTime")).value(subquery));
TypedQuery typedQuery = m_storage.createQuery(idQuery);
List<Long> ids = typedQuery.getResultList();
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.must(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
SearchOption searchOption = uriInfo.getSearchOption();
Query query = queryBuilder.bool()
.must(processSearchExpression(searchOption.getSearchExpression(), queryBuilder,
fields.toArray(new String[fields.size()]))).filteredBy(idJunction.createQuery())
.createQuery();
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, entityClass);
return fullTextQuery;
//fullTextQuery fails to run
如果我删除过滤器等
query = queryBuilder.bool()
.must(processSearchExpression(searchOption.getSearchExpression(), queryBuilder,
fields.toArray(new String[fields.size()])))
.createQuery();
查询运行但显然没有按 ID 过滤。过滤器中有id。当我将 showSQL 设置为 true 时,如果我没有过滤器,我会看到一个查询,但是当我有过滤器时,我没有得到显示的查询(但没有抛出错误)
我似乎找不到任何问题?!
我不确定你说的 "the query doesn't fire" 是什么意思:
- 如果你调用
typedQuery.getResultList();
,肯定执行了一个查询。 - Hibernate 搜索查询不使用 SQL,因此 "setting a showSQL to true" 无济于事。您需要使用与 trace Hibernate Search queries. 不同的选项
无论如何,我假设您的问题是查询没有 return 命中?这是您编写查询的方式的问题。你写了这个:
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.must(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
... 表示 "the field 'recId' must have every single one of these id values".
而不是 "must",您应该使用 "should":
BooleanJunction<?> idJunction = queryBuilder.bool();
for (Long id : ids) {
idJunction.should(queryBuilder.keyword().onField("recId").matching(id).createQuery());
}
... 表示 "the field 'recId' must have at least one of these id values".