Elasticsearch NEST частичное обновление анонимного объекта пустым вложенным объектом
Попытка "сбросить" вложенный объект в документе, но он не вернет его пустым.
У меня есть POCO:
public class StreetAddress
{
public int HouseNumber { get; set; }
public string Street { get; set; }
}
public class FullAddress
{
public string City{ get; set; }
public string State { get; set; }
public StreetAddress StreetAddress { get; set; }
public int Zip { get; set; }
public List<string> Codes { get; set; }
}
Поэтому в настоящее время, если я создал этот новый документ для FullAddress с уже установленным параметром StreetAddress, документ при запросе выглядит следующим образом:
"_source": {
"city": "Los Angeles",
"state": "California",
"zip": 90019,
"streetAddress": {
"houseNumber": 1,
"street": "Apple Street"
},
"codes" : [
{ "la-601" }
]
}
Теперь я хочу вызвать обновление клиента NEST для сброса вложенного объекта StreetAddress:
StreetAddress localStreetAddress = new StreetAddress();
var partialAddress = new
{
City = "NewCity",
Zip = 11111,
StreetAddress = localStreetAddress
};
this._client.Update<ElasticsearchProject, object>(update => update
.Id(1)
.Doc(partialAddress)
);
Окончательный результат, на который я надеялся, когда я запросил, будет после вышеуказанного вызова обновления:
"_source": {
"city": "NewCity",
"state": "California",
"zip": 11111,
"streetAddress": {}
}
Однако частичное обновление делает две вещи, которые нежелательны:
- Он только обновляет поля City и Zip и оставляет StreetAddress, как это было раньше, и не очищает его до пустого или нулевого.
- Он очищает список кодов для очистки, так как частичное обновление не включает список.
Я знаю, что могу установить для StreetAddress значение null и добавить свойство JSON для включения значения null следующим образом:
[JsonProperty(NullValueHandling = NullValueHandling.Include)]
public StreetAddress StreetAddress { get; set; }
но все, что может привести к тому, что при обновлении документа будет установлено пустое значение, а не пусто, и я не уверен, является ли это желаемым результатом для документа:
"_source": {
"city": "NewCity",
"state": "California",
"zip": 11111,
"streetAddress": null
}
Не уверен, что есть способ выполнить частичное обновление без перехода по пути к сценарию, чтобы вернуть вложенный объект обратно пустым.
1 ответ
Вложенные объекты фактически отображаются как отдельные скрытые документы в Elasticsearch, и, как вы обнаружили, NEST по умолчанию настроен так, чтобы не отправлять через нулевые значения. конечный результат заключается в том, что на вложенный тип не влияет частичное обновление свойств верхнего уровня.
Один из способов справиться с этим - просто переиндексировать документ снова без StreetAddress. Обновление - это удаление или вставка за кулисы.
В качестве примера
void Main()
{
var settings = new ConnectionSettings(new Uri("http://localhost:9200"), "address");
var client = new ElasticClient(settings);
// create the index
client.CreateIndex("address", c => c
.AddMapping<FullAddress>(m => m
.MapFromAttributes()
)
);
// index our document
client.Index(new FullAddress
{
City = "Los Angeles",
State = "California",
Zip = 90019,
Codes = new List<string>
{
"la-601"
},
StreetAddress = new StreetAddress
{
HouseNumber = 1,
Street = "Apple Street"
}
}, c => c.Id(1));
// Now at some later point, we need to update it,
// so get the current document
var response = client.Get<FullAddress>(1);
// make the changes to the current document
var address = response.Source;
address.StreetAddress = null;
// and re-index
client.Index<FullAddress>(address, c => c.Id(1));
}
public class StreetAddress
{
public int HouseNumber { get; set; }
public string Street { get; set; }
}
public class FullAddress
{
public string City { get; set; }
public string State { get; set; }
public StreetAddress StreetAddress { get; set; }
public int Zip { get; set; }
public List<string> Codes { get; set; }
}
Конечный результат, как и ожидалось
{
"_index": "address",
"_type": "fulladdress",
"_id": "1",
"_version": 2,
"found": true,
"_source": {
"city": "Los Angeles",
"state": "California",
"zip": 90019,
"codes": [
"la-601"
]
}
}
При этом вы также можете использовать оптимистический контроль параллелизма для обработки любых изменений между get
а также index
,