繁体   English   中英

如何使用 spring-data elasticsearch 对新添加的字段进行排序?

[英]How to sort on newly added field with spring-data elasticsearch?

我对 elasticsearch 和 spring-data 组合还很陌生。

让我给你一些背景知识。 我从这个实体开始

@Document(indexName = "my-entity")
public class MyEntity {
    @Id
    private String id;
    private String someField;
}

其中一些已创建并编入索引。 后来,我向实体添加了一个新字段。 现在它看起来像这样:

@Document(indexName = "my-entity")
public class MyEntity {
    @Id
    private String id;
    private String someField;
    @Field(type = FieldType.Date, format = DateFormat.date_time)
    private Date date;
}

我想要实现的是返回按我的新字段排序的所有实体(并非所有现有实体都有)。

最初我调整了我的Repository并定义了类似于List<MyEntity> findAllByOrderByDate(); ,但是当我尝试调用它时,出现以下异常:

"No mapping found for [date] in order to sort on"

我知道一个可能的解决方案是使用 elasticsearch 中的ignore_unmapped选项,但我的问题是:如何使用 spring-data-elasticsearch 实现这一点?

另一方面,我并没有固定使用Repository方法——我对解决方案持开放态度。

谢谢!

当你添加一个新的字段进行排序时,Elasticsearch 中的索引映射需要更新,否则 Elasticsearch 这个字段是什么类型。 Spring 数据 Elasticsearch 存储库不自动更新映射。

以下是检查 class(在此示例中名为Foo )的映射是否需要更新的方法:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.stereotype.Component;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com)
 */
@Component
public class FooMappingValidator {

    private static final Logger LOGGER = LoggerFactory.getLogger(FooMappingValidator.class);

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final ElasticsearchOperations operations;

    public FooMappingValidator(ElasticsearchOperations operations) {
        this.operations = operations;
    }

    @Autowired
    public void checkFooMapping() {

        var indexOperations = operations.indexOps(Foo.class);

        if (indexOperations.exists()) {
            LOGGER.info("checking if mapping for Foo changed");

            var mappingFromEntity = indexOperations.createMapping();
            var mappingFromEntityNode = objectMapper.valueToTree(mappingFromEntity);
            var mappingFromIndexNode = objectMapper.valueToTree(indexOperations.getMapping());

            if (!mappingFromEntityNode.equals(mappingFromIndexNode)) {
                LOGGER.info("mapping for class Foo changed!");
                indexOperations.putMapping(mappingFromEntity);
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM