Get by Id Missing in Current C#/NEST Documentation

Hello,

I am wondering what is the best way to query by document Id. In previous versions of the NEST documentation, there was an example of using the Get() method of the ElasticClient class, e.g. 1.x Documentation. The current documentation does not reference that field, and it seems that the method works differently now, requiring Document paths, e.g.:

var path = new DocumentPath<Type>(id).Type("_doc").Index("index-name");
var response = _elasticClient.Get(path);

or using the static method:

var path = DocumentPath<T>.Id(id).Type("_doc").Index("index-name");
var response = _elasticClient.Get(path);

Is this the recommended way to get an document by its Id? Or should we use the Ids query?

new IdsQuery
{
    Values = new List<Id> { id },
    Types = Type<ContactInfo>()
}

Or should we use a Match query on the _id field?

new MatchQuery
{
     Query = id
     Field = Infer.Field<Type>(t => t._id)
}

Thanks for your help,

Isaiah

Using the GET API is the recommended method.

A DocumentPath<T> is simply a type that can resolve a path from a POCO, so for example, if you have a POCO called ContactInfo that looks like

public class ContactInfo
{
	public string Id { get; set; }
	
	// other properties
}

You can retrieve a document using the Get API with

var getResponse = client.Get<ContactInfo>("<document id>");

This will make a request to the default index configured on ConnectionSettings, and infer the type name from the POCO type. For example, with the following

var defaultIndex = "my-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
    .DefaultIndex(defaultIndex);

var client = new ElasticClient(settings);

var getResponse = client.Get<ContactInfo>("<document id>");

The request will be sent to

GET http://localhost:9200/my-index/contactinfo/<document id>?

Now, you can also configure a default index and type name for ContactInfo on ConnectionSettings

var defaultIndex = "my-index";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
    .DefaultIndex(defaultIndex)
    .DefaultMappingFor<ContactInfo>(m => m
        .IndexName("contacts")
        .TypeName("doc")
    );


var client = new ElasticClient(settings);

var getResponse = client.Get<ContactInfo>("<document id>");

which will send a request to

GET http://localhost:9200/contacts/doc/<document id>

You can of course just pass the index and type name to use in the request

var getResponse = client.Get<ContactInfo>("<document id>", g => g
	.Index("another-index")
	.Type("another-type")
);

which sends a request to

GET http://localhost:9200/another-index/another-type/<document id>

Or you could construct a DocumentPath<T> as you're doing.

The intention with accepting a DocumentPath<T> as opposed to just an Id for the first parameter is that your application may have an instance of a POCO already, but may need to get an updated version from Elasticsearch. In this case, you can simply pass the POCO as the first parameter

var oldContactInfo = new ContactInfo { Id = "<document id>" };
var getResponse = client.Get<ContactInfo>(oldContactInfo);

And this will use the Id from the document, in addition to index name and type name that may be configured for the ContactInfo type.

Take a look at the documentation on DocumentPath<T> for further details

1 Like

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