Mongo更新数组元素(.NET驱动程序2.0)

Kri*_*ett 19 .net c# mongodb

编辑:不寻找这样做的javascript方式.我正在寻找MongoDB C#2.0驱动程序的方法(我知道它可能不可能;但我希望有人知道解决方案).

我试图在我的mongodb中更新主文档中数组中嵌入的项的值.

我正在寻找一种强有力的方式来做到这一点.我正在使用Mongodb c#2.0驱动程序

我可以通过弹出元素,更新值,然后重新插入来实现.这感觉不对劲; 因为我正在覆盖可能在此期间写的内容.

这是我到目前为止尝试但没有运气:

private readonly IMongoCollection<TempAgenda> _collection;

void Main()
{
    var collectionName = "Agenda";
    var client = new MongoClient("mongodb://localhost:27017");
    var db = client.GetDatabase("Test");
    _collection = db.GetCollection<TempAgenda>(collectionName);
    UpdateItemTitle(1, 1, "hello");
}

public void UpdateItemTitle(string agendaId, string itemId, string title){
    var filter = Builders<TempAgenda>.Filter.Eq(x => x.AgendaId, agendaId);
    var update = Builders<TempAgenda>.Update.Set(x => x.Items.Single(p => p.Id.Equals(itemId)).Title, title);
    var result = _collection.UpdateOneAsync(filter, update).Result;
}
Run Code Online (Sandbox Code Playgroud)

小智 51

我花了一些时间来弄清楚这一点,因为它似乎没有在任何官方文档(或其他任何地方)中提及.然而,我确实在他们的问题跟踪器上找到了这个,它解释了如何将位置运算符$与C#2.0驱动程序一起使用.

这应该做你想要的:

public void UpdateItemTitle(string agendaId, string itemId, string title){
    var filter = Builders<TempAgenda>.Filter.Where(x => x.AgendaId == agendaId && x.Items.Any(i => i.Id == itemId));
    var update = Builders<TempAgenda>.Update.Set(x => x.Items[-1].Title, title);
    var result = _collection.UpdateOneAsync(filter, update).Result;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您的Item.Single()子句已更改为Item.Any()并移至过滤器定义.

[-1]或者.ElementAt(-1)显然是专门处理的(实际上一切都是<0)并且将被位置操作员替换$.

以上内容将被翻译为此查询:

db.Agenda.update({ AgendaId: 1, Items.Id: 1 }, { $set: { Items.$.Title: "hello" } })
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了这个解决方案,代码实际上编译时没有任何错误,但是当我查询文档时在运行时会发生什么,该数组中的 [-1] 启动反向索引搜索而不是使用位置运算符。所以 -1 结果是数组的最后一个元素,-2 给出倒数第二个元素。这并不完全是我们想要的,索引应该通过位置运算符是动态的。 (2认同)