在DocumentDb中,是否可以搜索符合特定条件的子文档而无需在查询中涉及父类?
我(尝试开始)使用在创建新的Azure Cosmos数据库帐户时在Azure门户中自动生成的DocumentDbRepository.cs。但是,显而易见的是,这仅仅是一个起点,需要为个别情景做一些额外的工作。
在C#Console应用程序(.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; }
}
在Document Explorer中,我可以看到我有这样一个类结构的实例:
{
"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 ,无论他们属于哪个公司,我都不确定如何在存储库类中编写一个方法来完成此任务。
首先,我认为我需要某种类型的属性,因此我可以区分客户与员工的区别(与我可能也希望在同一集合中添加的其他域类类型相比)。
其次,我可能会查询为所有查询使用该类型属性,而不使用似乎只适用于根数据的DocumentDbRepository.cs方法。换句话说,DocumentDbRepository.cs方法似乎只关注非分层实体。
但这就是事情崩溃的地方......鉴于这个示例存储库类的通用特性,我无法将查询子文档/子项所需的点连接起来。
我只是要求在这里向正确的方向推进。谢谢。
答案 0 :(得分:3)
无论公司是什么,我都想检索员工
如果我理解正确,您希望根据员工查询员工&#39;来自客户的财产。如果是这种情况,我们可以使用SQL执行以下操作,我们只需要更改where&lt; filter_condition &gt;我们想要的。
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
}