spring-projects / spring-data-elasticsearch

Provide support to increase developer productivity in Java when using Elasticsearch. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-elasticsearch/
Apache License 2.0
2.92k stars 1.33k forks source link

How to retrieve stored fields with _source disabled? #2910

Closed debraj-manna closed 6 months ago

debraj-manna commented 6 months ago

I have an index template like below

{
  "index_patterns": [
    "request_response-*"
  ],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "index": {
        "codec": "best_compression"
      }
    },
    "mappings": {
      "_source": {
        "enabled": false
      },
      "properties": {
        "value": {
          "type": "binary",
          "store": true
        }
      }
    },
    "aliases": {
      "request_response": { }
    }
  },
  "priority": 500
}

Can someone let me know how can I execute the below query using spring-data-elasticsearch?

curl -X GET "localhost:9200/request_response-*/_search?stored_fields=value&pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "_id": {
        "value": "092d882489ea6dc4a6d2dc16d97fb72192b17ca97eaaca59961e97597b6ba80c"
      }
    }
  }
}
'

It returns the below result

{
  "took" : 11,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "request_response-2024-05-09",
        "_type" : "_doc",
        "_id" : "092d882489ea6dc4a6d2dc16d97fb72192b17ca97eaaca59961e97597b6ba80c",
        "_score" : 1.0,
        "fields" : {
          "value" : [
            "U29tZSBiaW5hcnkgYmxvYg=="
          ]
        }
      },
      {
        "_index" : "request_response-2024-05-10",
        "_type" : "_doc",
        "_id" : "092d882489ea6dc4a6d2dc16d97fb72192b17ca97eaaca59961e97597b6ba80c",
        "_score" : 1.0,
        "fields" : {
          "value" : [
            "U29tZSBiaW5hcnkgYmxvYg=="
          ]
        }
      }
    ]
  }
}

I tried the below

String documentId = "092d882489ea6dc4a6d2dc16d97fb72192b17ca97eaaca59961e97597b6ba80c";
    String[] storedFields = new String[]{"value"};
    IndexCoordinates indexCoordinates = IndexCoordinates.of("request_response-*");

    NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
        .withQuery(QueryBuilders.termQuery("_id", documentId))
        .withFields(storedFields)
        .build();

    SearchHits<KeyValueDoc> searchHits = elasticsearchOperations.search(searchQuery, KeyValueDoc.class, indexCoordinates);
    KeyValueDoc document = searchHits.getSearchHit(0).getContent();

But it is throwing the below error

Unable to retrieve the requested [fields] since _source is disabled in the mappings for index [request_response-2024-05-09

I asked the same query in the Opensearch forum here and I was suggested raising the issue with spring-data team as it is not an issue with Opensearch or elastic search and spring-data should add this support.

debraj-manna commented 6 months ago

I was able to figure this out. The below is working fine.

    NativeSearchQuery searchQuery =
        new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.termQuery("_id", doc.getKey()))
            .withStoredFields(new String[] {"value"})
            .build();
        elasticsearchOperations.search(
            searchQuery, KeyValueDoc.class, IndexCoordinates.of("request_response-*"));
sothawo commented 6 months ago

Spring Data Elasticsearch's Query implementations have a setStoredFields(List<String>) method as well.

Sometimes I wonder why people use Spring Data Elasticsearch at all when they always create queries with the native Elasticsearch methods.