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

时间:2017-03-22 06:02:44

标签: c# mongodb

我在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>
        }, 
        ....
    ]
}

我编写了这个mongodb查询,它的目的是找到给定_id的行,而不是更新其DeviceVersionPairs数组中匹配elemMatch过滤器的子文档,这实际上有效; < / p>

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

但我无法将其转换为与C#驱动程序(2.0.1.27)一起使用。到目前为止,我有这个,但这缺乏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;

使用C#驱动程序向mongodb发出此类请求的方式是什么?

2 个答案:

答案 0 :(得分:1)

最后,我提出了自己的解决方案。使用常规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)
    })))
});

答案 1 :(得分:0)

您是否尝试匹配阵列中的任何元素?如果是这样,这应该有效:

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;