gpt4 book ai didi

java - 在构建针对多个实体运行的通用 Lucene 查询时如何排除或忽略字段

转载 作者:行者123 更新时间:2023-12-02 11:01:53 33 4
gpt4 key购买 nike

我们正在将 Java 应用程序从使用 SOLR/Lucene 转换为 Elasticsearch 5.6.6。

在 1 个特定区域中,我们之前会构建 1 个 Lucene Search BooleanQuery 并针对 3 个不同的实体运行它,寻找匹配项。在您运行实际查询之前,我们不需要指定将使用它的实体。

 BooleanQuery luceneQuery = myQueryBuilder.buildMyQuery();
session.createFullTextQuery(luceneQuery, entityOne);
session.createFullTextQuery(luceneQuery, entityTwo);
session.createFullTextQuery(luceneQuery, entityThree);

上面 [luceneQuery] 中的一个子查询在taxId上进行搜索,entityOne没有该taxId(没有taxId索引字段),但其他2个实体有。然而,一切都工作正常,没有给出异常(exception),我相信它只是忽略了未知/未索引的字段,不完全确定它是如何工作的,但它确实如此。

现在我们正在转换为 Elasticsearch DSL,我们需要预先提供实体,以便我(无论好坏)针对每个实体构建查询 3 次不同的时间,如下所示:

 QueryBuilder entityOneQB = session.getSearchFactory().buildQueryBuilder().forEntity(EntityOne.class).get();
QueryBuilder entityTwoQB = session.getSearchFactory().buildQueryBuilder().forEntity(EntityTwo.class).get();
QueryBuilder entityThreeQB = session.getSearchFactory().buildQueryBuilder().forEntity(EntityThree.class).get();
// Create 3 exact (except for which entity they point at) queries
Query entityOneQuery = myQueryBuilder.buildMyQuery(entityOne);
Query entityTwoQuery = myQueryBuilder.buildMyQuery(entityTwo);
Query entityThreeQuery = myQueryBuilder.buildMyQuery(entityThree);

其中 buildMyQuery() 有许多子查询,但处理taxId的子查询看起来像:

 qb.bool().should(
qb.keyword()
.onField("taxId")
.matching(taxId)
.createQuery()
);

但是,现在,entityOne 没有taxId 作为索引列/字段,createQuery() 会抛出异常:

 SearchException: Unable to find field taxId in EntityOne

我的问题是:

  1. 如果实体没有该字段,是否有某种方法告诉 Lucene 忽略该字段?

  2. 如果没有,是否有某种方法,使用传入的 QueryBuilder 来确定实体是什么,这样,在taxId子查询代码中,我基本上可以说 if (entityType == EntityOne) { return null;} 以便该特定子查询不会包含在整个查询中?

最佳答案

Is there some way to tell Lucene to ignore the field if the entity doesn't have it?

澄清一下:实现 DSL 并抛出异常的是 Hibernate Search,而不是 Lucene。 Lucene是底层技术,并没有进行太多验证。

如果您的目标是检索单个结果列表中的所有三个实体,并且不同实体类型中具有相同名称的字段配置类似(例如字段“名称”出现在实体 1 和 2 中,但具有相同的分析器),您可以简单地构建一个查询并检索该查询中的所有三种类型。您必须:

  • 确保在构建单个 Lucene 查询时,始终使用实际定义您的定位字段的实体类型的查询构建器:if Targeting taxId例如,您可以使用 EntityTwo 的查询生成器或 EntityThree ,但不是 EntityOne 的那个。是的,没错:您可以在单个查询中混合使用多个查询构建器,只要在所有目标实体中配置相同名称的字段即可。
  • 构建FullTextQuery这样:session.createFullTextQuery(luceneQuery, EntityOne.class, EntityTwo.class, EntityThree.class);

If not, is there some way, using the passed in QueryBuilder to determine what the entity is, so that, within the taxId subquery code, I can basically say if (entityType == EntityOne) {return null;} so that this particular sub-query won't be included in the overall query?

不,没有。不过,您可以向方法添加一个参数来传递实体类型:buildMyQuery(Class<?> type, QueryBuilder queryBuilder)而不是buildMyQuery(QueryBuilder queryBuilder) .

关于java - 在构建针对多个实体运行的通用 Lucene 查询时如何排除或忽略字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51273154/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com