代码之家  ›  专栏  ›  技术社区  ›  garfbradaz Vivek

COSMOSDB-子文档删除选择-LINQ查询

  •  0
  • garfbradaz Vivek  · 技术社区  · 7 年前

    我有一个 ProductDocument CosmosDB中的模型,表示产品。在这个模型中有一个子文档 contributors 其中包含谁对产品做出了贡献。每个贡献者都有一个 role 是的。

    现在我正在尝试一个查询,它需要:

    1. 只选择 产品文档 用一个 contributor.roleDescription 属于 作者
    2. 只选择 产品文档 用一个 division 属于 发布1
    3. 只包括 贡献者 子文档带有 贡献者角色描述 属于 作者 在结果集中。

    现在我在挣扎:

    1. 以上选择的第3部分。如何完成这一点,因为我的结果集包括 贡献者角色描述 属于 作者 以及 插图画家

    宇宙模型示例:

    [
    
        {
            "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"
                }
            ]
    
        }]
    

    这是我在 数据资源管理器 以下内容:

    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>());
            }
    

    它选择正确的记录,但如何取消选择 插图画家 贡献者的子文档,因为目前我得到了以下信息:

       {
            "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"
                }
    
            ]
    
        }
    

    编辑:

    1. 我想过滤一下 Product 如果其中一个子文档 贡献者角色描述 等于作者。因此,如果产品记录中没有作者贡献者,我不希望

    2. 我想包括每个 contributor 等于的子文档 作者 是的。因此,如果 产品 ,我想包括它们,但不包括 插图画家 一个。

    3. 你可以收集 ProductDocuments 是的。

    4. 对流畅的linq语法有很大帮助。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Krishnan Sundaram    7 年前

    azure cosmosdb现在支持子查询。使用子查询,您可以通过两种方式执行此操作,但略有不同:

    1. 可以在投影中使用带有子查询的数组表达式,过滤掉不需要的贡献者,并投影所有其他属性。此查询假定您需要一个选定的属性列表,以便在数组之外进行投影。

      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”上过滤,然后在子查询中过滤数组表达式。

    1. 或者,如果希望整个文档与筛选的参与者一起使用,可以执行以下操作:

      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”分区投影原始文档,并在标记为“contributors”的属性中单独使用筛选的contributor数组。您可以为筛选的参与者引用此参与者数组,而忽略文档中的参与者。

        2
  •  0
  •   Brandon Minnick    7 年前

    这将做你想做的,但显然如果你有多个贡献者,你想展示它可能不会完全做你想做的-很难用你的问题来判断这是否是你真正想要的

    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"
            }
        }
    ]
    

    请注意,贡献者不是一个列表,而是一个单独的值,因此如果多个贡献者与过滤器匹配,那么您将得到同一产品多次返回。

    推荐文章