如何避免使用Nest .NET 6.x将重复项发布到elasticsearch?

问题描述 投票:1回答:2

当来自设备的数据进入弹性时,存在重复数据。我想避免这种重复。我正在使用IElasticClient,.NET和NEST的对象来放置数据。

我搜索了像ElasticClient.SetDocumentId()这样的方法,但无法找到。

_doc doc = (_doc)obj;
HashObject hashObject = new HashObject { DataRecordId = doc.DataRecordId, TimeStamp = doc.Timestamp };
// hashId should be the document ID.
int hashId = hashObject.GetHashCode();
ElasticClient.IndexDocumentAsync(doc);

我想更新Elastic中的数据集,而不是立即添加一个相同的对象。

c# .net elasticsearch nest
2个回答
1
投票

假设以下设置

var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
    .DefaultIndex("example")
    .DefaultTypeName("_doc");

var client = new ElasticClient(settings);

public class HashObject
{
    public int DataRecordId { get; set; }
    public DateTime TimeStamp { get; set; }
}

如果要在请求中明确设置文档的Id,可以使用

Fluent syntax

var indexResponse = client.Index(new HashObject(), i => i.Id("your_id"));

Object initializer syntax

var indexRequest = new IndexRequest<HashObject>(new HashObject(), id: "your_id");   
var indexResponse = client.Index(indexRequest);

两者都会导致请求

PUT http://localhost:9200/example/_doc/your_id
{
  "dataRecordId": 0,
  "timeStamp": "0001-01-01T00:00:00"
}

正如Rob在问题评论中指出的那样,NEST有一个约定,通过查找名为Id的CLR POCO上的属性,它可以从文档本身推断Id。如果找到一个,它将使用它作为文档的Id。这确实意味着Id值最终存储在_source中(并且已编入索引,但您可以在映射中禁用它),但它很有用,因为Id值会自动与文档关联并在需要时使用。

如果HashObject更新为具有Id值,现在我们可以这样做

Fluent syntax

var indexResponse = client.IndexDocument(new HashObject { Id = 1 });

Object initializer syntax

var indexRequest = new IndexRequest<HashObject>(new HashObject { Id = 1});  
var indexResponse = client.Index(indexRequest);

这将发送请求

PUT http://localhost:9200/example/_doc/1
{
  "id": 1,
  "dataRecordId": 0,
  "timeStamp": "0001-01-01T00:00:00"
}

如果您的文档在id中没有_source字段,则您需要自己处理来自每次点击的点击元数据中的_id值。例如

var searchResponse = client.Search<HashObject>(s => s
    .MatchAll()
);

foreach (var hit in searchResponse.Hits)
{
    var id = hit.Id;
    var document = hit.Source;

    // do something with them
}

0
投票

非常感谢Russ对这个详细易懂的描述! :-)

HashObject应该只是从我的真实_doc对象中获取唯一ID的帮助器。现在我将一个Id属性添加到我的_doc类中,其余的我将使用下面的代码显示。我现在再次复制到弹性中。

public void Create(object obj)
{
    _doc doc = (_doc)obj;
    string idAsString = doc.DataRecordId.ToString() + doc.Timestamp.ToString();
    int hashId = idAsString.GetHashCode();
    doc.Id = hashId;
    ElasticClient.IndexDocumentAsync(doc);
}
© www.soinside.com 2019 - 2024. All rights reserved.