Как избежать размещения дубликатов вasticsearch с помощью Nest .NET 6.x? - PullRequest
1 голос
/ 08 апреля 2019

Когда данные с устройства переходят в эластичное поле, появляются дубликаты.Мне нравится избегать дублирования .Я использую объект 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 вместо добавления еще одного такого же объекта прямо сейчас.

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

Предполагая следующую настройку

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 для документа явно по запросу, вы можете сделать это с помощью

Свободный синтаксис

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

Синтаксис инициализатора объекта

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"
}

Как указал Роб в комментариях к вопросу, NEST имеет соглашение, согласно которому он может вывести Id из самого документа путем поиска свойства в CLR POCO с именем Id. Если он найдет его, он будет использовать его в качестве идентификатора для документа. Это означает, что значение Id в конечном итоге сохраняется в _source (и индексируется, но вы можете отключить это в сопоставлениях), но это полезно, поскольку значение Id автоматически связывается с документом и используется при необходимости.

Если HashObject обновлен, чтобы иметь значение Id, теперь мы можем просто сделать

Свободный синтаксис

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

Синтаксис инициализатора объекта

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 голосов
/ 09 апреля 2019

Большое спасибо, Расс, за это подробное и простое для понимания описание! : -)

HashObject должен быть просто помощником для получения уникального идентификатора из моего реального объекта _doc.Теперь я добавляю свойство Id к своему классу _doc, а остальное я покажу с моим кодом ниже.Теперь я получаю дубликаты в Elastic.

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);
}
...