简体   繁体   English

Mongodb使用C#驱动程序使用多个字段匹配更新嵌入式文档

[英]Mongodb Update Embedded Documents Using Multiple Field Matches with C# driver

I have a document structure on mongodb like below: 我在mongodb上有一个文档结构,如下所示:

{
    _id: <string>,
    field1: ...,
    field2: ...,
    field3: ...,
    DeviceVersionPairs: [{ 
            DeviceId: <ObjectId>, 
            CloudFolderId: <ObjectId>, 
            CloudFileId: <ObjectId>, 
            VersionId: <ObjectId>, 
            Status: <int>
        },{ 
            DeviceId: <ObjectId>, 
            CloudFolderId: <ObjectId>, 
            CloudFileId: <ObjectId>, 
            VersionId: <ObjectId>, 
            Status: <int>
        }, 
        ....
    ]
}

I wrote this mongodb query, it is designed to find the row with the _id given than update the subdocument in its DeviceVersionPairs array matching the elemMatch filter, which actually works; 我写这MongoDB的查询,它的目的是找到具有该行_id比更新其子文档给出DeviceVersionPairs阵列匹配elemMatch过滤器,它的实际工作;

db.deduplications.update({
    "_id": "...", 
    "DeviceVersionPairs": { "$elemMatch" : {
        "DeviceId": ObjectId("..."), 
        "CloudFolderId": ObjectId("..."), 
        "CloudFileId": ObjectId("..."), 
        "VersionId": ObjectId("...")
    }}
},{
    "$set": { "DeviceVersionPairs.$.Status": 100 }
}, false, false)

But I can't convert it to use with C# driver(2.0.1.27). 但我无法将其转换为与C#驱动程序(2.0.1.27)一起使用。 So far I had this, but this lacks the elemMatch statement, hence it doesn't work as expected. 到目前为止,我有这个,但这缺乏elemMatch语句,因此它没有按预期工作。

var p = DbContext.Deduplications.FindOneAndUpdateAsync(
    filter: Builders<Dal.Deduplication>.Filter.And(
        Builders<Dal.Deduplication>.Filter.Eq("_id", fileHash),
        Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.DeviceId", deviceId),
        Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.CloudFolderId", CloudFolderId),
        Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.CloudFileId", FileId),
        Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.VersionId", versionIdToBeRemoved)),
    update: Builders<Dal.Deduplication>.Update.Set("DeviceVersionPairs.$.Status", DVPStatus.PassiveOrDeleted)).Result;

What is the way to make such a request to mongodb using C# driver? 使用C#驱动程序向mongodb发出此类请求的方法是什么?

Finally I've come up with my own solution. 最后,我想出了自己的解决方案。 Creating the filter using the regular BsonDocument objects did the job. 使用常规BsonDocument对象创建过滤器完成了这项工作。

var filter = new BsonDocument(new List<BsonElement> {
    new BsonElement("_id", fileHash),
    new BsonElement("DeviceVersionPairs", new BsonDocument("$elemMatch", new BsonDocument(new List<BsonElement> {
        new BsonElement("DeviceId", deviceId),
        new BsonElement("CloudFolderId", cloudFolderId),
        new BsonElement("CloudFileId", cloudFileId),
        new BsonElement("VersionId", versionId)
    })))
});

Are you trying to match on any element inside the array? 您是否尝试匹配阵列中的任何元素? If so this should work: 如果是这样,这应该工作:

var p = DbContext.Deduplications.FindOneAndUpdateAsync(
filter: Builders<Dal.Deduplication>.Filter.AnyEq(
    Builders<Dal.Deduplication>.Filter.Eq("_id", fileHash),
    Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.DeviceId", deviceId),
    Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.CloudFolderId", CloudFolderId),
    Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.CloudFileId", FileId),
    Builders<Dal.Deduplication>.Filter.Eq("DeviceVersionPairs.VersionId", versionIdToBeRemoved)),
update: Builders<Dal.Deduplication>.Update.Set("DeviceVersionPairs.$.Status", DVPStatus.PassiveOrDeleted)).Result;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM