gpt4 book ai didi

elasticsearch - 带有空嵌套对象的匿名对象的Elasticsearch NEST部分更新

转载 作者:行者123 更新时间:2023-12-03 00:17:54 25 4
gpt4 key购买 nike

尝试“重置”文档中的嵌套对象,但不会将其设置为空。

我有一个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; }
}

因此,当前,如果我已经使用StreetAddress为FullAddress创建了这个新文档,则在查询时该文档看起来像这样:
"_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。
  • 由于部分更新不包含代码列表,因此将代码列表清除为空。

  • 我知道我可以将StreetAddress设置为null并添加JSON属性以包括null,如下所示:
    [JsonProperty(NullValueHandling = NullValueHandling.Include)]
    public StreetAddress StreetAddress { get; set; }

    但是结果就是文档更新会将其设置为null而不是空,而且我不确定这是否是文档的理想结果:
    "_source": {          
    "city": "NewCity",
    "state": "California",
    "zip": 11111,
    "streetAddress": null
    }

    不知道是否有一种方法可以进行部分更新,而不必沿脚本路径进行操作以将嵌套对象设置为空。

    最佳答案

    实际上,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来处理 getindex之间的所有更改。

    关于elasticsearch - 带有空嵌套对象的匿名对象的Elasticsearch NEST部分更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34424404/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com