I have a ProductDocument
model in CosmosDB, which represents a Product. Within that model there is a subdocument contributors
which holds who has contributed to the Product. Each contributor has a role
.
Now I have been experimenting with a query that needs to:
- Only select
ProductDocument
with acontributor.roleDescription
of Author - Only select
ProductDocument
with adivision
of Pub 1 - Only include
contributors
sub documents with acontributor.roleDescription
of Author in the result set.
Now I'm struggling with:
- Part 3 of select above. How do I accomplish this bit as my result set is including both
contributor.roleDescription
of Author AND Illustrator
Example Cosmos Model:
[
{
"id": "1",
"coverTitle": "A Title",
"pubPrice": 2.99,
"division" :"Pub 1",
"Availability": {
"code": "20",
"description": "Digital No Stock"
},
"contributors": [
{
"id": 1,
"firstName": "Brad",
"lastName": "Smith",
"roleDescription": "Author",
"roleCode": "A01"
},
{
"id": 2,
"firstName": "Steve",
"lastName": "Bradley",
"roleDescription": "Illustrator",
"roleCode": "A12"
}
]
},
{
"id": "2",
"coverTitle": "Another Title",
"division" :"Pub 2",
"pubPrice": 2.99,
"Availability": {
"code": "50",
"description": "In Stock"
},
"contributors": [
{
"id": 1,
"firstName": "Gareth Bradley",
"lastName": "Smith",
"roleDescription": "Author",
"roleCode": "A01"
}
]
}]
Here is my SQL which I have been playing around with in the Data Explorer:
SELECT VALUE p
FROM Products p
JOIN c IN p.contributors
WHERE c.roleDescription = 'Author'
AND p.division = 'Pub 1'
Here is my LINQ query from my service:
var query = client.CreateDocumentQuery<ProductDocument>(
UriFactory.CreateDocumentCollectionUri("BiblioAPI", "Products"),
new FeedOptions
{
MaxItemCount = -1,
EnableCrossPartitionQuery = true
}
)
.SelectMany(product => product.Contributors
.Where(contributor => contributor.RoleDescription == "Author")
.Select(c => product)
.Where(p => product.Division == "Pub 1"))
.AsDocumentQuery();
List<ProductDocument> results = new List<ProductDocument>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<ProductDocument>());
}
It selects the correct records, but how do I de-select the Illustrator sub document of contributor, because at the moment I get the following:
{
"id": "1",
"coverTitle": "A Title",
"pubPrice": 2.99,
"division" :"Pub 1",
"Availability": {
"code": "20",
"description": "Digital No Stock"
},
"contributors": [
{
"id": 1,
"firstName": "Brad",
"lastName": "Smith",
"roleDescription": "Author",
"roleCode": "A01"
},
{
"id": 2,
"firstName": "Steve",
"lastName": "Bradley",
"roleDescription": "Illustrator",
"roleCode": "A12"
}
]
}
But the following output is what I want, excluding the Illustrator contributor sub document:
{
"id": "1",
"coverTitle": "A Title",
"pubPrice": 2.99,
"division" :"Pub 1",
"Availability": {
"code": "20",
"description": "Digital No Stock"
},
"contributors": [
{
"id": 1,
"firstName": "Brad",
"lastName": "Smith",
"roleDescription": "Author",
"roleCode": "A01"
}
]
}
EDIT:
I would like to filter on
Product
if one of the subdocumentcontributor.roleDescription
equals Author. So if the Product record doesn't include a Author contributor I don't want itI want to include each
contributor
subdocument that equals Author. So if there are multiple Author contributor subdocuments for aProduct
, I want to include them, but exclude the Illustrator ones.You could have a Collection of
ProductDocuments
.Help on the fluent LINQ syntax would help greatly.