Elasticsearch-net: ES document's _id is not mapped to C# entity's Id

Created on 3 Aug 2018  路  5Comments  路  Source: elastic/elasticsearch-net

I have simplistic entity with property named "Id" of type String in my C# code.
I also have an index with a number of documents uploaded via Bulk API. Document's schema doesn't include "id" field. The only thing that I have is a standard Elasticsearch's "_id" property.

So when it gets to retrieving documents (var response = _esClient.Search<Poco>(s => s.MatchAll())), I clearly see that Id has correct value in every object in response's Hits array property.
However, when I do var documents = response.Documents.ToList(), all my documents has Id = null.

What I've tried is setting IdProperty in ConnectionSettings - still no luck. So I don't really see a way to map Elasticsearch's "_id" to my entity's Id property.

Description of the problem including expected versus actual behavior:

NEST/Elasticsearch.Net version: latest
Elasticsearch version: latest

Steps to reproduce:

  1. Create Elasticsearch index with documents.
  2. Create simplest entity with Id property.
  3. var documents = _esClient.Search<Poco>(s => s.MatchAll()).Documents.ToList()

ER: documents is a list of Pocos where each object has Id property equal to corresponding document's "_id" field in Elasticsearch.
AR: Id = null in all objects.

ConnectionSettings:

            _settings =
                new ConnectionSettings(_node)
                    .DefaultIndex("pocos")
                    .DefaultTypeName("doc")

                    .DefaultMappingFor<Poco>(
                        m => m
                            .IndexName("pocos")
                            .TypeName("doc")
                            .IdProperty(p => p.Id));  // this one doesn't work anyway
            _esClient = new ElasticClient(_settings);
Discuss

Most helpful comment

@maxsel It's intentional behaviour and by design to not map the _id in the hit metadata returned for a hit to an Id property on a POCO during deserialization. It's been discussed quite a few times before, the most recent is https://github.com/elastic/elasticsearch-net/issues/1293. It can be mapped with

```c#
var response = client.Search(searchDescriptor);

var pocoListWithIds = response.Hits.Select(h =>
{
h.Source.Id = h.Id;
return h.Source;
}).ToList();
```

Thoughts on revisiting this @Mpdreamz and @codebrain ? I have some thoughts about Elasticsearch autogenerated Ids that could tie in with this i.e. exposing the ability to configure on ConnectionSettings to

  1. Allow Elasticsearch to generate Ids for documents
  2. Allow _id hit metadata to the POCO (on responses where this data is available).

All 5 comments

@maxsel It's intentional behaviour and by design to not map the _id in the hit metadata returned for a hit to an Id property on a POCO during deserialization. It's been discussed quite a few times before, the most recent is https://github.com/elastic/elasticsearch-net/issues/1293. It can be mapped with

```c#
var response = client.Search(searchDescriptor);

var pocoListWithIds = response.Hits.Select(h =>
{
h.Source.Id = h.Id;
return h.Source;
}).ToList();
```

Thoughts on revisiting this @Mpdreamz and @codebrain ? I have some thoughts about Elasticsearch autogenerated Ids that could tie in with this i.e. exposing the ability to configure on ConnectionSettings to

  1. Allow Elasticsearch to generate Ids for documents
  2. Allow _id hit metadata to the POCO (on responses where this data is available).

Thanks for explanation @russcam, duplicating document's hit metadata "_id" in the source as document's "id" field worked for us. Though it's an obvious duplication, the code looks much better without that explicit mapping :)

I'm new to Nest and ElasticSearch but one vote for remove the one way mapping OR make it 2 way.
Thanks! B-)

We discussed this again recently and voted to close this issue based on the following:

  • The Id is currently a one-way mapping for indexing, simply for the purposes of making the indexing API easy to use.
  • It is possible do disable Id inference already with DefaultDisableIdInference
  • You are able to put the document Id into another property, so that it is retained on _source and set it to not indexed in the mapping.
  • Creating a 2-way mapping doesn't make sense for many of the big data use cases, where documents inherently do not have an Id (logs, SIEM data, time series and append-only indices)
  • It is reasonably easy to implement your own mapping from Hits into your POCO as shown here: https://github.com/elastic/elasticsearch-net/issues/3350#issuecomment-410618969

So for now we shall close, unless there is a compelling reason to re-open.

@codebrain I thought I noticed this behavior in a recent version of NEST. I remember having an Id field set automatically somehow, but it's possible that I handled this with AutoMapper and forgot about it.
Is there an equivalent for the Version property to automatically retrieve and store the version information without additional mapping?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

russcam picture russcam  路  3Comments

joostvz picture joostvz  路  3Comments

hatem1975 picture hatem1975  路  3Comments

Mpdreamz picture Mpdreamz  路  5Comments

alwag85 picture alwag85  路  5Comments