如何使用Elasticsearch Nest客户端通过_id查询特定文档

问题描述

我有一个要检索的特定文档。 id值是通过弹性搜索分配的,因此不会出现在文档的_source部分中。

我相信应该有一个Ids函数,但是我在nesT文档中找不到它。 结果如下: Cannot convert lambda expression to type 'Id' because it is not a delegate type

var queryResponse = 
  client.Search<Dictionary<string,object>>(
    s => s.Query(
      q => q.Ids( 
        i => i.Values(v => "_id_assigned_by_elastic")
      )
    )
  ).Hits.FirstOrDefault();

Dictionary<string,object> doc = h.source;

Rest api文档显示了此示例:

{
  "query": {
    "ids" : {
      "values" : ["1","4","100"]
    }
  }
}

没有C#和nesT客户端的相应示例

解决方法

在将文档索引到Elasticsearch中时未指定ID时,Elasticsearch将自动生成该文档的ID。该ID将在索引响应中返回,并且是文档元数据的一部分。相反,发送到Elasticsearch的JSON文档将保留为文档的_source

假设JSON文档使用以下POCO建模

public class MyDocument
{
    public string Property1 { get; set; }
}

在使用Nest索引到Elasticsearch时获取文档的ID

var client = new ElasticClient();

var document = new MyDocument
{
    Property1 = "foo"
};

var indexResponse = client.Index(document,i => i.Index("my_documents"));

var id = indexResponse.Id;

使用ID,可以使用Get API

检索文档
var getResponse = client.Get<MyDocument>(id,g => g.Index("my_documents"));
    
var fetchedDocument = getResponse.Source;

getResponse除包含源外,还包含文档元数据,例如索引,序列号,路由等。

还有Source API,可用于仅检索文档_source

var sourceResponse = client.Source<MyDocument>(id,g => g.Index("my_documents"));
    
var fetchedDocument = sourceResponse.Body;

如果要按ID检索许多文档,可以使用MultiGet API

var ids = new long[] { 1,2,3 };

var multiGetResponse = client.MultiGet(m => m
    .Index("my_documents")
    .GetMany<MyDocument>(ids,(g,id) => g.Index(null))
);


var fetchedDocuments = multiGetResponse.GetMany<MyDocument>(ids).Select(h => h.Source);

Multi Get API可以针对跨不同索引的文档,这些文档可能会映射到应用程序中的不同POCO。

最后,如果您想在搜索时按文档ID的子集进行过滤,则可以使用IDs查询

var ids = new long[] { 1,3 };

var multiGetResponse = client.Search<MyDocument>(s => s
    .Index("my_documents")
    .Query(q => q
        .Ids(i => i
            .Values(ids)
        )
    )
);

请注意,在对Get,Source和MultiGet API进行索引后,它们可以立即检索文档。相比之下,只有刷新索引后,索引文档才会显示在搜索结果中。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...