当前位置: 首页 > 知识库问答 >
问题:

在Spring data elasticsearch中,如何在所有结果上投影或添加计算字段?

时经纬
2023-03-14

我正在使用spring-data-elasticsearch(最新版本)以及elasticsearch(最新版本)的docker实例,我想在查询后从我的存储库返回的所有结果上计算一个字段。我不想在存储库中使用这些信息,因为它有时依赖于查询,有时依赖于环境。例如,如果我们执行查询,我想生成一个URL,其中包含查询词作为URL中的查询参数,我想用它来丰富结果。还有一些其他情况。我尝试创建一个接受整个文档对象的Spring data自定义读取转换器。我可以看到它在应用程序启动时被识别,但从未被调用。如何使用自定义值投影字段,或使用上下文计算的值丰富返回的文档?

共有2个答案

齐弘业
2023-03-14

我喜欢一种混合的方法,将“ChinHuang”和“PJMeisch”的答案结合起来。这两个答案都有其适用性,这取决于语境或情况。我喜欢黄的建议,比如基于实例的信息,你需要配置值之类的东西。我也同意PJ Meisch的担忧是正确的,即这不会让您访问即时查询,因此我喜欢他在从数据存储返回数据时拦截/映射值的想法。我感谢两人提供的大量信息,因为这两种方法的结合是一种我很满意的解决方案。

我更喜欢尽可能使用存储库接口,因为许多人错误地将业务逻辑混合到他们的存储库中。如果我想要自定义实现,那么我必须真正考虑它,因为我必须创建一个“Impl”类来实现它。这不是最严重的错误,但我总是伴随着存储库的业务服务,该服务负责任何数据梳理,或任何不严格检索或持久化数据的编程操作。

这是我的模块配置的一部分,在这里我创建了自定义的AfterConvertCallback。我在onAfterConvert方法中设置了基本URL:

@Bean
AfterConvertCallback<BookInfo> bookInfoAfterConvertCallback() {
    return new BookInfoAfterConvertCallback(documentUrl);
}

static class BookInfoAfterConvertCallback implements AfterConvertCallback<BookInfo> {

    private final String documentUrl;

    public BookInfoAfterConvertCallback(String documentUrl) {
        this.documentUrl = documentUrl;
    }

    @Override
    public BookInfo onAfterConvert(final BookInfo entity, final Document document, final IndexCoordinates indexCoordinates) {
        entity.setUrl(String.format("%s?id=%d", documentUrl, entity.getId()));
        return entity;
    }
}

在调用存储库查询的数据服务中,我编写了一对函数来创建URL的查询参数部分,以便我可以将其附加到使用自动连接存储库实例的任何适用方法中:

/**
 * Given a term, encode it so that it can be used as a query parameter in a URL
 */
private static final Function<String, String> encodeTerm = term -> {
    try {
        return URLEncoder.encode(term, StandardCharsets.UTF_8.name());
    } catch (UnsupportedEncodingException e) {
        log.warn("Could not encode search term for document URL", e);
        return null;
    }
};

/**
 * Given a list of search terms, transform them into encoded URL query parameters and append
 * them to the given URL.
 */
private static final BiFunction<List<String>, String, String> addEncodedUrlQueryParams = (searchTerms, url) ->
        searchTerms.stream()
                .map(term -> String.format("term=%s", encodeTerm.apply(term)))
                .filter(Objects::nonNull)
                .collect(Collectors.joining("&", url + "&", ""));

这完全可以在存储库实例或其封闭服务中完成。但是,当您想要截取检索到的所有数据,并对其执行非特定于查询的操作时,回调是一个很好的选择,因为它不会产生需要在其应应用的每个数据层方法中引入回调的维护成本。在查询时,当您需要引用仅在查询中可用的信息时,显然需要将此类代码引入数据层(服务或repo)方法。

添加这一点作为回答,因为即使我在发布问题时没有意识到这一点,但这两个问题是相互独立的,足以保证两种方法都适用。我不想为这个答案索赔,所以我不会选择它作为答案,除非你们都对此发表评论,并告诉我,你希望我这样做。

王凯旋
2023-03-14

我首先想到了AfterConvertCallback以及Chin评论,但是在回调中,您没有运行以获取实体的查询的上下文,因此您不能使用查询术语之类的东西来构建某些东西。

我会将属性-让我们在此处将其命名为类型为Stringurl-添加到实体中,并使用org.springframework.data.annotation.瞬态注释对其进行标记,以防止其被存储。

然后在您进行搜索的方法中,使用Elasticsearch chAction或存储库,对返回的实体进行后处理(代码未测试,只是写在这里):

SearchHits<Entity> searchHits = repository.findByFoo(String fooValue);
searchHits.getSearchHits().forEach(searchHit -> {
    searchHit.getContent().setUrl(someValueDerivedFromEnvironemtAndQuery);
});

之后继续使用SearchHits

 类似资料:
  • 我正在这样访问我的存储库中的投影。

  • 我创建这段代码是为了创建随机数和运算符,但它如何计算并显示结果呢? 它现在做的是,例如打印出来:4+1-3或9*2-8等。我不知道如何计算出4+1-3或9*2-8的结果,然后打印出来。

  • 本文向大家介绍如何在JavaFX中的文本节点上添加阴影效果?,包括了如何在JavaFX中的文本节点上添加阴影效果?的使用技巧和注意事项,需要的朋友参考一下 您可以使用setEffect()方法将效果添加到JavaFX中的任何节点对象。此方法接受Effect类的对象,并将其添加到当前节点。 javafx.scene.effect.DropShadow类表示投影效果。此效果使用指定的参数(颜色,偏移量

  • 我正在尝试从下面的查询收集表格中获取数据: 但如果$match的集合中存在datat,则会导致空数据,但此slug的job\u活动不存在 有人能帮忙吗谢谢

  • 假设我有 100 个带字段的文档 地址 现在假设我的业务模式正在改变,我想添加新的现场呼叫。 如何在所有100个文档中添加?NoSQL数据库上有这样的东西吗?

  • 我需要按、和的间隔(步长为5)对数据进行分组。对于每个组,我要估计中位数 我可以分组数据并计算的中值,但是我不知道如何添加的间隔: 正确的应该结构如下(数字可能不同,这只是数据结构的一个例子): 更新: 最终结果应该是这样的。因此,基本上,和分别是上下限: