如何使用 .NET 中的 NEST 库在 ElasticSearch 中创建带有索引的文档?

How to create document with an index in ElasticSearch using NEST library in .NET?

我第一次尝试在 C# 中使用弹性搜索,我正在尝试创建一个类似于 sql 中的一行的文档。

据我了解,索引类似于 table,文档是一行。我尝试使用 CreateDocumentAsync 方法,但它没有任何参数可传入索引,因此我不确定如何创建具有特定索引的文档。我不能使用默认索引,因为我们的产品可以有很多索引。首先,我检查索引是否存在,如果不存在,则创建索引,然后创建文档

这里有一些代码

public async Task<CreateResponse> CreateDocumentAndIndex<T>(T document, string index) where T : class
{
    CreateResponse response = new(); 
    if (_client.Indices.Exists(index).Exists)
    {
        response = await _client.CreateDocumentAsync<T>(document);
    }
    else
    {
        await _client.IndexAsync(document, idx => idx.Index(index));
        response = await _client.CreateDocumentAsync<T>(document);
    }         
    return response;
}

现在要使用它,我有一个调用此方法的函数

var response = await elasticSearchClient.CreateDocumentAndIndex<DbContextEventData>(eventData,"test");

但是在尝试创建文档时出现错误。在 elastic search

中创建 row/document 时有没有办法传入索引

问题已标记elasticsearch-5,因此假设您使用的是 NEST 5.6.6,则可以在创建文档的同时指定索引

var client = new ElasticClient();

var createResponse = await client.CreateAsync(new { foo = "bar" }, c => c
    .Index("my-index") // index
    .Type("_doc") // document type
    .Id("1") // document id
);

编辑:

由于您使用的是 Elasticsearch 6.3.0,因此您必须 使用最新的 NEST 6.x 客户端,在撰写本文时为 6.8.10。使用 NEST 6.8.10,创建文档 API 调用如下

private static void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
    var settings = new ConnectionSettings(pool)
        .DisableDirectStreaming()
        .PrettyJson()
        .DefaultTypeName("_doc") // doc types are gone in future versions, so best to index with this default doc type name
        .OnRequestCompleted(LogToConsole);
        
    var client = new ElasticClient(settings);
    
    if (client.IndexExists("my-index").Exists) 
    {
        client.DeleteIndex("my-index");
    }

    var document = new MyDocument
    {
        Foo = "Bar",
        Baz = 1
    };

    var createResponse = client.Create(document, c => c
        .Index("my-index") // index
        .Id("1") // document id
    );
    
    var returnedDocument = client.Get<MyDocument>("1", g => g.Index("my-index"));
}

public class MyDocument
{
    public string Foo { get; set; }
    
    public int Baz { get; set; }
}

private static void LogToConsole(IApiCallDetails callDetails) 
{
    if (callDetails.RequestBodyInBytes != null)
    {
        var serializer = new JsonSerializer();
        var jObjects = new List<JObject>();
        using (var sr = new StringReader(Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)))
        using (var jsonTextReader = new JsonTextReader(sr))
        {
            jsonTextReader.SupportMultipleContent = true;
            while (jsonTextReader.Read())
                jObjects.Add((JObject)JObject.ReadFrom(jsonTextReader));
        }

        var formatting = jObjects.Count == 1
            ? Newtonsoft.Json.Formatting.Indented
            : Newtonsoft.Json.Formatting.None;
        var json = string.Join("\n", jObjects.Select(j => j.ToString(formatting)));
        Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri} \n{json}");
    }
    else
    {
        Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
    }

    Console.WriteLine();

    if (callDetails.ResponseBodyInBytes != null)
    {
        Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                 $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
                 $"{new string('-', 30)}\n");
    }
    else
    {
        Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                 $"{new string('-', 30)}\n");
    }
}

将以下内容记录到控制台

PUT http://localhost:9200/my-index/_doc/1/_create?pretty=true
{
  "foo": "Bar",
  "baz": 1
}

Status: 201
{
  "_index" : "my-index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

------------------------------

GET http://localhost:9200/my-index/_doc/1?pretty=true

Status: 200
{
  "_index" : "my-index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "foo" : "Bar",
    "baz" : 1
  }
}

------------------------------