linq 无法将多个更新定义更新到MongoDB

x6yk4ghg  于 2023-03-27  发布在  Go
关注(0)|答案(1)|浏览(98)

我正在尝试更新ResolvedItems下的ErrorMessage字段,但我收到一个错误MongoDB驱动程序:不支持表达式。我尝试了下面的代码,如果我设置像BundleName这样的字段,它就可以工作。但是ErrorMessage无法这样做,因为它在多个地方,而且我不确定这个linq是否有问题。

MongoDB Collection :

     {
           "_id" : 
            {
              "$oid": "97368836hsh987"
              },
              "Type": "DataModel",
              "BundleId": "4587654",
              "BundleName": "Work_Bundle"
              "Collection": 
              {
                "Items":[
                {
                "_id": "3046",
                "ResolvedItems":[
                {
                "_id":"45687",
                "Url": "abc@xyz.com",
                "ErrorMessage": ""
                },
                {
                "_id":"4789",
                "Url": "def@xyz.com",
                "ErrorMessage": ""
                },
                {
                "_id":"9874",
                "Url": "ghi@xyz.com",
                "ErrorMessage": ""
                }
                ]
                }
                ]
              }
        }

My C# Code to update DB :

        List<UpdateDefinition<DataModel>> updateDefinitions = new ();
        foreach(string urlItem in liUrl)
        {
        updateDefinition = Builders<DataModel>.Update.Set( p=> p.Collection.Items.SelectMany(item => item.ResolvedItems.Where(resItem => resItem.Url.Equals(urlItem)).SelectMany(x=>x.ErrorMessage)), "ErrorMessage");
        }
        
        await DbConnection.UpdateByKey("BundleId","4587654", Builders<DatModel>.Update.Combine(updateDefinitions));
pxq42qpu

pxq42qpu1#

对于MongoDB .NET驱动程序版本2.16及以上,它支持positional operatorLinqProvider.V3
先决条件:您需要在MongoClientSettings中启用LinqProvider.V3

MongoClientSettings settings = MongoClientSettings.FromConnectionString(
    /* MongoDB Connection string */
);
settings.LinqProvider = MongoDB.Driver.Linq.LinqProvider.V3;

MongoClient _client = new MongoClient(settings);
using MongoDB.Driver.Linq;

UpdateDefinition<DataModel> updateDefinition = Builders<DataModel>.Update
    .Set(p => p.Collection
        .Items.AllElements()
        .ResolvedItems.AllMatchingElements("ri")
        .ErrorMessage, "ErrorMessage");

List<ArrayFilterDefinition> arrayFilters = new List<ArrayFilterDefinition>
{
    new BsonDocumentArrayFilterDefinition<Item>
    (
        new BsonDocument
        {
            {
                "ri.Url", new BsonDocument
                {
                    { "$in", BsonArray.Create(liUrl) }
                }
            }
        }
    )
};

UpdateOptions updateOptions = new UpdateOptions
{
    ArrayFilters = arrayFilters
};

UpdateResult result = await _collection.UpdateOneAsync(x => x.BundleId == "4587654",
    updateDefinition,
    updateOptions);

如果你使用的是2.16之前的版本,LINQ方式似乎很难实现,相反,你应该提供带有位置操作符的更新键。

UpdateDefinition<DataModel> updateDefinition = Builders<DataModel>.Update
    .Set("Collection.Items.$[].ResolvedItems.$[ri].ErrorMessage", "ErrorMessage");
  • 在2.16及以上版本的方法中替换updateDefinition变量。*

对于MongoDB查询:

db.collection.update({
  "BundleId": "4587654"
},
{
  $set: {
    "Collection.Items.$[].ResolvedItems.$[ri].ErrorMessage": "ErrorMessage"
  }
},
{
  arrayFilters: [
    {
      "ri.Url": {
        $in: [
          "abc@xyz.com",
          "def@xyz.com"
        ]
      }
    }
  ]
})

相关问题