CosmosDB - 子文档删除选择 - LINQ 查询
CosmosDB - SubDocument Delselecting - LINQ Query
我在 CosmosDB 中有一个 ProductDocument
模型,它代表一个产品。在该模型中有一个子文档 contributors
,其中包含谁为产品做出了贡献。每个贡献者都有一个 role
.
现在我一直在试验需要的查询:
- 只有 select
ProductDocument
contributor.roleDescription
的 作者
- 只有 select
ProductDocument
division
的 Pub 1
- 在结果集中仅包含
contributors
个 contributor.roleDescription
的 作者 的子文档。
现在我正在努力:
- 上面 select 的第 3 部分。我如何完成这一点,因为我的结果集包括 Author 和 Illustrator
的 contributor.roleDescription
示例 Cosmos 模型:
[
{
"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"
}
]
}]
这是我的 SQL,我一直在 Data Explorer 中使用:
SELECT VALUE p
FROM Products p
JOIN c IN p.contributors
WHERE c.roleDescription = 'Author'
AND p.division = 'Pub 1'
这是来自我的服务的 LINQ 查询:
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>());
}
它 select 是正确的记录,但是我如何 de-select Illustrator 贡献者的子文档,因为此刻我得到以下:
{
"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"
}
]
}
但下面的输出是我想要的,不包括 Illustrator contributor 子文档:
{
"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"
}
]
}
编辑:
如果其中一个子文档 contributor.roleDescription
等于作者,我想过滤 Product
。因此,如果产品记录不包含作者贡献者,我不想要它
我想包含等于 Author 的每个 contributor
子文档。因此,如果 Product
有多个 Author contributor 子文档,我想包括它们,但排除 Illustrator。
你可以有 ProductDocuments
的 Collection。
有关流利的 LINQ 语法的帮助将大有帮助。
这会做你想做的,但很明显,如果你有多个贡献者,你想展示它可能不会做你想要的 - 很难用你的问题来判断这是否正是你想要的
SELECT p.id, p.coverTitle, p.pubPrice, p.division, p.Availability, c as contributors
FROM Products p
JOIN c IN p.contributors
WHERE c.roleDescription = 'Author'
AND p.division = 'Pub 1'
输出为:
[
{
"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"
}
}
]
请注意,contributors 不是列表,它是单个值,因此如果多个 contributors 匹配过滤器,那么您将多次返回相同的产品。
Azure CosmosDB 现在支持子查询。使用子查询,您可以通过两种方式执行此操作,但略有不同:
您可以在投影中使用带有子查询的 ARRAY 表达式,过滤掉不需要的贡献者,并投影所有其他属性。此查询假定您需要一个 select 属性列表来投影数组。
SELECT c.id, c.coverTitle, c.division, ARRAY(SELECT VALUE contributor from contributor in c.contributors WHERE contributor.roleDescription = "Author") contributors
FROM c
WHERE c.division="Pub 1"
这假设您需要首先对除法 "Pub 1" 进行过滤,然后是带有 ARRAY 表达式的子查询。
或者,如果您想要整个文档以及过滤后的贡献者,您可以这样做:
SELECT c, ARRAY(SELECT VALUE contributor from contributor in c.contributors WHERE contributor.roleDescription = "Author") contributors
FROM c
WHERE c.division="Pub 1"
这将在标记为 "c" 的 属性 中投影带有 "Pub 1" 分部的原始文档,以及在标记为 [=] 的 属性 中单独过滤的贡献者数组33=]。您可以为过滤后的贡献者引用此贡献者数组,而忽略文档中的贡献者。
我在 CosmosDB 中有一个 ProductDocument
模型,它代表一个产品。在该模型中有一个子文档 contributors
,其中包含谁为产品做出了贡献。每个贡献者都有一个 role
.
现在我一直在试验需要的查询:
- 只有 select
ProductDocument
contributor.roleDescription
的 作者 - 只有 select
ProductDocument
division
的 Pub 1 - 在结果集中仅包含
contributors
个contributor.roleDescription
的 作者 的子文档。
现在我正在努力:
- 上面 select 的第 3 部分。我如何完成这一点,因为我的结果集包括 Author 和 Illustrator 的
contributor.roleDescription
示例 Cosmos 模型:
[
{
"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"
}
]
}]
这是我的 SQL,我一直在 Data Explorer 中使用:
SELECT VALUE p
FROM Products p
JOIN c IN p.contributors
WHERE c.roleDescription = 'Author'
AND p.division = 'Pub 1'
这是来自我的服务的 LINQ 查询:
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>());
}
它 select 是正确的记录,但是我如何 de-select Illustrator 贡献者的子文档,因为此刻我得到以下:
{
"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"
}
]
}
但下面的输出是我想要的,不包括 Illustrator contributor 子文档:
{
"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"
}
]
}
编辑:
如果其中一个子文档
contributor.roleDescription
等于作者,我想过滤Product
。因此,如果产品记录不包含作者贡献者,我不想要它我想包含等于 Author 的每个
contributor
子文档。因此,如果Product
有多个 Author contributor 子文档,我想包括它们,但排除 Illustrator。你可以有
ProductDocuments
的 Collection。有关流利的 LINQ 语法的帮助将大有帮助。
这会做你想做的,但很明显,如果你有多个贡献者,你想展示它可能不会做你想要的 - 很难用你的问题来判断这是否正是你想要的
SELECT p.id, p.coverTitle, p.pubPrice, p.division, p.Availability, c as contributors
FROM Products p
JOIN c IN p.contributors
WHERE c.roleDescription = 'Author'
AND p.division = 'Pub 1'
输出为:
[
{
"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"
}
}
]
请注意,contributors 不是列表,它是单个值,因此如果多个 contributors 匹配过滤器,那么您将多次返回相同的产品。
Azure CosmosDB 现在支持子查询。使用子查询,您可以通过两种方式执行此操作,但略有不同:
您可以在投影中使用带有子查询的 ARRAY 表达式,过滤掉不需要的贡献者,并投影所有其他属性。此查询假定您需要一个 select 属性列表来投影数组。
SELECT c.id, c.coverTitle, c.division, ARRAY(SELECT VALUE contributor from contributor in c.contributors WHERE contributor.roleDescription = "Author") contributors FROM c WHERE c.division="Pub 1"
这假设您需要首先对除法 "Pub 1" 进行过滤,然后是带有 ARRAY 表达式的子查询。
或者,如果您想要整个文档以及过滤后的贡献者,您可以这样做:
SELECT c, ARRAY(SELECT VALUE contributor from contributor in c.contributors WHERE contributor.roleDescription = "Author") contributors FROM c WHERE c.division="Pub 1"
这将在标记为 "c" 的 属性 中投影带有 "Pub 1" 分部的原始文档,以及在标记为 [=] 的 属性 中单独过滤的贡献者数组33=]。您可以为过滤后的贡献者引用此贡献者数组,而忽略文档中的贡献者。