尝试重置"文档中的嵌套对象,但不会将其设置为空。
我有一个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": {}
}
但是,部分更新会做两件不受欢迎的事情:
我知道我可以将StreetAddress设置为null并添加JSON属性以包含null,如下所示:
[JsonProperty(NullValueHandling = NullValueHandling.Include)]
public StreetAddress StreetAddress { get; set; }
但是所有这一切都会导致文档更新将其设置为null而不是为空,我不确定这是否是文档的预期结果:
"_source": {
"city": "NewCity",
"state": "California",
"zip": 11111,
"streetAddress": null
}
不确定是否有办法在不下载脚本路径的情况下进行部分更新,以将嵌套对象设置为空。
答案 0 :(得分:0)
Nested objects实际上是在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"
]
}
}
您也可以在执行此操作时使用optimistic concurrency control来处理get
和index
之间的任何更改。