How to save elasticsearch date type in spring data?

Hi there,
I want to use spring data to get elasticsearch documents, but encountered some problems with get data.
Here is my code.
Entity:

    @Id
    private String id;

    @Field(name = "@timestamp", type = FieldType.Date)
    private Date timestamp;

    @Field(name = "netflow.first_switched", type = FieldType.Date)
    private Date firstSwitched;

    @Field(name = "netflow.last_switched", type = FieldType.Date)
    private Date lastSwitched;

My data in elasticsearch:
註解 2020-07-08 101000

I want to test spring data can get document or not(implement ElasticsearchRepository), so I hard code ID like:
Optional<OriginalData> a = originalDataService.findById("nfQ8KHMBB49SfiIiH2rK");

And then I got an exception:
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2020-07-07T07:44:54.878Z'; nested exception is java.lang.IllegalArgumentException

so I modify my Entity code to

    @Id
    private String id;

//    @Field(name = "@timestamp", type = FieldType.Date)
//    private Date timestamp;

    @Field(name = "netflow.first_switched", type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    private LocalDateTime firstSwitched;

    @Field(name = "netflow.last_switched", type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    private LocalDateTime lastSwitched;

still wrong, but got another exception:
org.springframework.data.elasticsearch.core.convert.ConversionException: could not create object of class java.time.LocalDateTime

My questions are:

  1. How to use spring data get elasticsearch document with field containing data type?
  2. I want to get field "@timestamp", can I get this?

Does anyone can help me, please?
Kase

Didn't solve this problem..., I use Java High Level REST Client instead of old way.
And faced another problem, I want to ask how to use rest client to get documents with matching multiple fields?

I have tried

public SearchHits findSymmetry(String srcAddr, String dstAddr, Long srcPort, Long dstPort, String ipProtocol, long tos, String id) {
    MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
    SearchRequest searchRequest = new SearchRequest();
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.termsQuery("flow.src_addr", srcAddr));
    searchRequest.source(searchSourceBuilder);
    multiSearchRequest.add(searchRequest);
    searchSourceBuilder.query(QueryBuilders.termsQuery("flow.dst_addr", dstAddr));
    searchRequest.source(searchSourceBuilder);
    multiSearchRequest.add(searchRequest);
    try {
        MultiSearchResponse response = client.msearch(multiSearchRequest,RequestOptions.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

When I build my project, IDE shown me error

Error:(87, 48) java: reference to termsQuery is ambiguous
  both method termsQuery(java.lang.String,double...) in org.elasticsearch.index.query.QueryBuilders and method termsQuery(java.lang.String,java.lang.Object...) in org.elasticsearch.index.query.QueryBuilders match
Error:(90, 48) java: reference to termsQuery is ambiguous
  both method termsQuery(java.lang.String,double...) in org.elasticsearch.index.query.QueryBuilders and method termsQuery(java.lang.String,java.lang.Object...) in org.elasticsearch.index.query.QueryBuilders match
Error:(96, 48) java: reference to termsQuery is ambiguous
  both method termsQuery(java.lang.String,double...) in org.elasticsearch.index.query.QueryBuilders and method termsQuery(java.lang.String,java.lang.Object...) in org.elasticsearch.index.query.QueryBuilders match

Is that mean I could only search limit two fields?
Does anyone can help me, please?
Kase

I found answer.

    public SearchHits findSymmetry(String srcAddr, String dstAddr, long srcPort, long dstPort, String ipProtocol, long tos, String id) {
        BoolQueryBuilder query = QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("flow.src_addr", srcAddr))
                .must(QueryBuilders.termsQuery("flow.dst_addr", dstAddr))
                .must(longTermsQuery("flow.src_port", srcPort))
                .must(longTermsQuery("flow.dst_port", dstPort))
                .must(QueryBuilders.termsQuery("flow.ip_protocol", ipProtocol))
                .must(longTermsQuery("flow.tos", tos));
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(query);
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            return searchResponse.getHits();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static TermsQueryBuilder longTermsQuery(String name, long... values) {
        return new TermsQueryBuilder(name, values);
    }

Thank you for following people!

@kase
MultiSearchRequest is used batch multiple independent queries. You want to match document where both src_addr and dst_addr match to respective values.

Not tested but following should give you the idea.

SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(
                QueryBuilders.boolQuery()
                .filter(QueryBuilders.termsQuery("flow.src_addr", srcAddr))
                .filter(QueryBuilders.termsQuery("flow.dst_addr", destAddr)));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

this is equivalent of ( (flow.src_addr = srcAddr) AND (flow.dst_addr = destAddr) ). If you need OR instead of AND, replace "filter" by "should"

1 Like

Hi @Vinayak_Sapre, thanks for your answering, problem has solved!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.