Mongodb update inline documents using multiple field matches with c # driver

I have a document structure on mongodb like below:

{
    _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 for looking for a string with _id

specified than updating a subdocument in an array DeviceVersionPairs

matching a filter elemMatch

that actually works;

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

      

But I cant convert it to use with C # driver (2.0.1.27). So far I have had it, but it is missing an instruction elemMatch

, so it doesn't work as expected.

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 mongodb request using the C # driver?

+3


source to share


2 answers


Finally I came up with my own solution. Creating a filter using regular objects BsonDocument

did the job.



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


source


Are you trying to match any element within the array? If so, then 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;

      

0


source







All Articles