#c# #.net #elasticsearch #nest
#c# #.net #elasticsearch #гнездо
Вопрос:
Когда данные с устройства поступают в эластичный файл, появляются дубликаты. Мне нравится избегать этих дубликатов. Я использую объект 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);
Я хотел бы обновить набор данных внутри эластичного, вместо того, чтобы добавлять еще один такой же объект прямо сейчас.
Комментарии:
1. Это должно вам помочь elastic.co/guide/en/elasticsearch/client/net-api/current /…
2. Нет, это что-то другое.
3. Я подумал, что если вы назначите идентификатор объекту doc и используете обновление с upsert , это поможет здесь.
Ответ №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; }
}
Если вы хотите явно указать идентификатор документа в запросе, вы можете сделать это с помощью
Свободный синтаксис
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 есть соглашение, согласно которому он может выводить идентификатор из самого документа, ища свойство в CLR POCO с именем Id
. Если он найдет один, он будет использовать его в качестве идентификатора для документа. Это означает, что значение идентификатора в конечном итоге сохраняется в _source
(и индексируется, но вы можете отключить это в сопоставлениях), но это полезно, потому что значение идентификатора автоматически связывается с документом и используется при необходимости.
Если 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
}
Ответ №2:
Большое вам спасибо, Расс, за это подробное и понятное описание! 🙂
HashObject должен быть просто помощником для получения уникального идентификатора из моего реального объекта _doc. Теперь я добавляю свойство 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);
}