I’m having difficulties putting up a code which returns an element in an array of subdocuments. I am actually trying to flatten a document to a new document which is strongly typed. My document is looking like;
{
"_id" : BinData(3, "7FRf4nbe60ev6XmGKBBW4Q=="),
"status" : NumberInt(1),
"title":"Central station",
"attributes" : [
{
"defId" : BinData(3, "QFDtR03NbkqwuhhG76wS8g=="),
"value" : "388",
"name" : null
},
{
"defId" : BinData(3, "RE3MT3clb0OdLEkkqhpFOg=="),
"value" : "",
"name" : null
},
{
"defId" : BinData(3, "pPgJR50h8kGdDaCcH2o17Q=="),
"value" : "Merkez",
"name" : null
}
]}
What I am trying to achieve is;
{
"title":"Central Station",
"value":"388"
}
What I’ve done already;
using (_dbContext)
{
var filter = Builders<CustomerModel>.Filter.Eq(q => q.Id, Guid.Parse("30B59585-CBFC-4CD5-A43E-0FDB0AE3167A")) &
Builders<CustomerModel>.Filter.ElemMatch(f => f.Attributes, q => q.DefId == Guid.Parse("47ED5040-CD4D-4A6E-B0BA-1846EFAC12F2"));
var projection = Builders<CustomerModel>.Projection.Include(f => f.Title).Include("attributes.value");
var document = _dbContext.Collection<CustomerModel>().Find(filter).Project(projection).FirstOrDefault();
if (document == null)
return null;
return BsonSerializer.Deserialize<TitleAndValueViewModel>(document);
}
Note: TitleAndCodeViewModel contains title and value properties.
This block of code returns;
{{ "_id" : CSUUID("30b59585-cbfc-4cd5-a43e-0fdb0ae3167a"), "title" : "388 güvenevler", "attributes" : [{ "value" : "388" }, { "value" : "" }, { "value" : "Merkez " }] }}
I am trying to get "value":"388" but instead I am getting another two value properties even tough the ElemMatch filter added for subdocument.
Thank you for your help in advance.
Note: I am looking for answers in C# mongodb driver.
2
Answers
by specifying
defId
result:
Option 1: ( via aggregation)
Explained:
Playground
Option 2: ( find/$elemMatch )
Explained:
( Note this version will not identify if there is second attribute with same attribute.defId , also projection of attribute will be array with single element if found that need to be considered from the app side )
Playground 2