【问题标题】:DocumentDb Repository to Query Child Documents GenericallyDocumentDb 存储库,用于一般查询子文档
【发布时间】:2017-07-04 16:53:41
【问题描述】:

在 DocumentDb 中,是否可以搜索满足特定条件的子文档,而不必让父类参与查询?

背景

当您创建新的 Azure Cosmos DB 帐户时,我正在(尝试开始)使用在 Azure 门户中自动为您生成的 DocumentDbRepository.cs。但是,很明显,这只是一个起点,需要针对个别场景进行一些额外的工作。

在 C# 控制台应用程序 (.NET Core) 中,我在公司和员工之间有一个简单的父子关系:

public class Customer
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "location")]
    public string Location { get; set; }

    [JsonProperty(PropertyName = "employees")]
    public List<Employee> Employees { get; set; }

    public Customer()
    {
        Employees = new List<Employee>();
    }
}

public class Employee
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "firstName")]
    public string FirstName { get; set; }

    [JsonProperty(PropertyName = "lastName")]
    public string LastName { get; set; }

    [JsonProperty(PropertyName = "sales")]
    public double Sales { get; set; }

}

在文档资源管理器中,我可以看到我有一个此类结构的实例,如下所示:

{
  "id": "7",
  "name": "ACME Corp",
  "location": "New York",
  "employees": [
    {
      "id": "c4202793-da55-4324-88c9-b9c9fe8f4b6c",
      "firstName": "John",
      "lastName": "Smith",
      "sales": 123
    }
  ]
}

如果我想获得所有满足特定条件的公司,使用生成的 DocumentDbRepository.cs 方法将是一个相当简单的操作:

DocumentDBRepository<Customer>.Initialize();
var customers = DocumentDBRepository<Customer>.GetItemsAsync(p => p.Location.Equals("New York")).Result;

...作为参考,Microsoft 方法生成的 GetItemsAsync() 如下所示:

    public static async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate)
    {
        IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
                UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
                new FeedOptions { MaxItemCount = -1 })
            .Where(predicate)
            .AsDocumentQuery();

        List<T> results = new List<T>();
        while (query.HasMoreResults)
        {
            results.AddRange(await query.ExecuteNextAsync<T>());
        }

        return results;
    }

问题

但是,如果我想检索 ONLY EMPLOYEES 而不管他们属于哪个公司,我不确定如何在存储库类中编写一个方法来完成此操作。

首先,我认为我需要某种类型属性,以便区分什么是 Customer 和一个 Employee(相对于我可能还想添加到同一个集合中的其他域类类型)。

其次,我可能会使用该类型属性来查询所有查询,而不是使用似乎仅适用于根数据的 DocumentDbRepository.cs 方法。换句话说,DocumentDbRepository.cs 方法似乎只关注非分层实体。

但这就是问题所在......鉴于此示例存储库类的通用性质,我无法将查询子文档/子文档所需的点连接起来。

我只是在这里寻求正确方向的推动。谢谢。

【问题讨论】:

    标签: azure-cosmosdb


    【解决方案1】:

    无论公司如何,我都只想检索 EMPLOYEES

    如果我理解正确,您想根据客户的员工属性查询员工。如果是这种情况,我们可以使用如下 SQL 来实现,我们只需要根据需要更改 where filter_condition>。

    SELECT c as employees
    FROM c IN Customer.employees
    WHERE c.firstName = 'John' 
    

    我在 Azure 门户中使用您提到的文档进行了测试,它在我这边可以正常工作。

    以下是c#演示代码:

    var endpointUrl = "https://yourdocumentdbname.documents.azure.com:443/";
    var authorizationKey = "xxxxx";
    var databaseId = "database name";
    var collectionId = "collecton name";
    var client =  new DocumentClient(new Uri(endpointUrl), authorizationKey);
    var sql = "SELECT c as employee FROM c IN Customer.employees WHERE c.firstName = 'xx'";
    var collection = client.CreateDocumentCollectionIfNotExistsAsync(
                UriFactory.CreateDatabaseUri(databaseId), new DocumentCollection
                {
                    Id = collectionId
    
                }).Result.Resource;
    var query = client.CreateDocumentQuery(collection.SelfLink, sql).AsDocumentQuery();
    
    while (query.HasMoreResults)
    {
      var documents =  query.ExecuteNextAsync().Result;
      //do something
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多