I have the following data structure:
[
{
"id": "604ab2c4a568b9181987c9eb",
"name": "Paul",
"eventDate": "2021-03-12T00:16:03.672Z",
"created": "2021-03-12T00:16:03.673Z",
"images": [
{
"id": "604ab2c3a568b9181987c603",
"name": "DSC_0",
"url": "https://picsum.photos/300/300",
"isSelected": true
},
...
]
},
{
"id": "604ab3889c5ac2289b450e3c",
"name": "Paul",
"eventDate": "2021-03-12T00:16:03.672Z",
"created": "2021-03-12T00:16:03.673Z",
"images": [
{
"id": "604ab3879c5ac2289b450a54",
"name": "DSC_0",
"url": "https://picsum.photos/300/300",
"isSelected": true
},
...
]
},
...
]
and im trying to get the image by the user id and the image id, but i cant for some reason
var filter = Builders<Client>.Filter.Eq("Id", "604ab2c4a568b9181987c9eb");
filter &= Builders<Client>.Filter.ElemMatch(u => u.Images,t => t.Id == "604ab2c3a568b9181987c603");
return _client.Find(filter).FirstOrDefault();
This is giving me back all the document with the id "604ab2c4a568b9181987c9eb", but i just wanted to receive the image with the id "604ab2c3a568b9181987c603"
Here the models of the objects:
public class Client
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("name")]
public string Name { get; set; }
[BsonElement("eventDate")]
[BsonDateTimeOptions]
public DateTime EventDate { get; set; }
[BsonElement("created")]
[BsonDateTimeOptions]
public DateTime Created { get; set; }
[BsonElement("images")]
public List<Image> Images { get; set; }
}
public class Image
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("name")]
public string Name { get; set; }
[BsonElement("url")]
[DataType(DataType.ImageUrl)]
public string Url { get; set; }
[BsonElement("isSelected")]
public bool IsSelected { get; set; }
}
So i wanted to know how could i fix my code to make it give me back just an image, or more than one images from the user im searching.
Last but not least, i wanted to know if i can change the isSelected value even if im using the same filter.
You wanted to use projection for only asking for the specific Image with the given id. So the query would look like>
var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<Client>("clients");
//collection.InsertOne(new Client
//{
// Created = DateTime.Now,
// EventDate = DateTime.Now,
// Name = "myClient",
// Images = new List<Image>
// {
// new Image
// {
// Id = ObjectId.GenerateNewId(DateTime.Now).ToString(),
// Name = "Image1",
// IsSelected = true,
// Url = "myUrl1"
// },
// new Image
// {
// Id = ObjectId.GenerateNewId(DateTime.Now).ToString(),
// Name = "Image2",
// IsSelected = true,
// Url = "myUrl2"
// }
// }
//});
var filter = Builders<Client>.Filter.Eq("Id", "605a60a76b25fefcc3b1bc00");
var imageFilter = Builders<Image>.Filter.Eq("Id", "605a60a76b25fefcc3b1bbff");
var projection = (ProjectionDefinition<Client, Client>)Builders<Client>.Projection.ElemMatch("Images", imageFilter);
var image = collection.Find(filter).Project(projection).FirstOrDefault() // here you have the specific client with only the right Image in the Images. Other props are default.
?.Images?[0]; // selecting the only Image in the list.
Sorry, but the update part is not that simple. Taking a whole different approach>
var filter = Builders<Client>.Filter.Eq(x => x.Id, "605a60a76b25fefcc3b1bc00");
var update = Builders<Client>.Update.Set("images.$[f].isSelected", false);
var arrayFilters = new[]
{
new BsonDocumentArrayFilterDefinition<BsonDocument>(
new BsonDocument("f._id", BsonObjectId.Create("605a60a76b25fefcc3b1bbff")))
};
collection.UpdateOne(filter, update, new UpdateOptions { ArrayFilters = arrayFilters });
Mostly taken from https://kevsoft.net/2020/03/23/updating-arrays-in-mongodb-with-csharp.html