elasticsearch,nest,C#,elasticsearch,Nest" /> elasticsearch,nest,C#,elasticsearch,Nest" />

C# 当文档存在时,如何在不更新的情况下将文档批量插入ElasticSearch

C# 当文档存在时,如何在不更新的情况下将文档批量插入ElasticSearch,c#,elasticsearch,nest,C#,elasticsearch,Nest,我正在用Nest库使用弹性搜索。我想知道当文档存在时,如何在不更新的情况下将文档批量插入ElasticSearch?下面是一个执行创建操作的批量API调用示例 private static void Main() { var defaultIndex = "documents"; var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); var settings = new Con

我正在用Nest库使用弹性搜索。我想知道当文档存在时,如何在不更新的情况下将文档批量插入ElasticSearch?

下面是一个执行创建操作的批量API调用示例

private static void Main()
{
    var defaultIndex = "documents";
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var settings = new ConnectionSettings(pool)
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);

    client.Index(new MyDocument(1) 
    { 
        Message = "new" 
    }, i => i.Refresh(Refresh.WaitFor));

    var documents = new [] 
    {
        new MyDocument(1) { Message = "updated" },
        new MyDocument(2) { Message = "updated" },
        new MyDocument(3) { Message = "updated" },
    };

    client.Bulk(b => b
        .CreateMany(documents)
        .Refresh(Refresh.WaitFor)
    );

    var getResponse = client.Get<MyDocument>(1);

    Console.WriteLine(getResponse.Source.Message == "new");
}

public class MyDocument 
{
    public MyDocument(int id) => Id = id;

    public int Id { get; set; }  

    public string Message { get; set; }
}
重要的是,
“errors”
true
,第一个
“create”
操作响应指示错误是什么

使用
.CreateMany(…)
的另一种方法是将
.UpdateMany(…)
与upsert操作一起使用,在文档存在的情况下指定“no op”操作

client.Bulk(b => b
    .UpdateMany(documents, (d, document) => d
        .Upsert(document)
        .Script(s => s
            .Source("ctx.op = 'none'")
        )
    )
    .Refresh(Refresh.WaitFor)
);
结果是相同的,即Id为
1
的文档不会被覆盖,但响应略有不同

{
  "took" : 1307,
  "errors" : false,
  "items" : [
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "1",
        "_version" : 1,
        "result" : "noop",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "status" : 200
      }
    },
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "2",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "3",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

请注意,
“errors”
现在是
false
,第一个
“update”
操作是
“noop”

,下面是一个执行创建操作的批量API调用示例

private static void Main()
{
    var defaultIndex = "documents";
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var settings = new ConnectionSettings(pool)
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);

    client.Index(new MyDocument(1) 
    { 
        Message = "new" 
    }, i => i.Refresh(Refresh.WaitFor));

    var documents = new [] 
    {
        new MyDocument(1) { Message = "updated" },
        new MyDocument(2) { Message = "updated" },
        new MyDocument(3) { Message = "updated" },
    };

    client.Bulk(b => b
        .CreateMany(documents)
        .Refresh(Refresh.WaitFor)
    );

    var getResponse = client.Get<MyDocument>(1);

    Console.WriteLine(getResponse.Source.Message == "new");
}

public class MyDocument 
{
    public MyDocument(int id) => Id = id;

    public int Id { get; set; }  

    public string Message { get; set; }
}
重要的是,
“errors”
true
,第一个
“create”
操作响应指示错误是什么

使用
.CreateMany(…)
的另一种方法是将
.UpdateMany(…)
与upsert操作一起使用,在文档存在的情况下指定“no op”操作

client.Bulk(b => b
    .UpdateMany(documents, (d, document) => d
        .Upsert(document)
        .Script(s => s
            .Source("ctx.op = 'none'")
        )
    )
    .Refresh(Refresh.WaitFor)
);
结果是相同的,即Id为
1
的文档不会被覆盖,但响应略有不同

{
  "took" : 1307,
  "errors" : false,
  "items" : [
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "1",
        "_version" : 1,
        "result" : "noop",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "status" : 200
      }
    },
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "2",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "documents",
        "_type" : "mydocument",
        "_id" : "3",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}
请注意,
“errors”
现在是
false
,而第一个
“update”
操作是
“noop”