我在Azure CosmosDB中有一个集合,每个文档都是这样的:
{
"id": "random",
"TeacherName": "Ben",
"Students": [
{
"Name": "John",
"Telephone": ""
},
{
"Name": "Mary",
"Telephone": ""
}
],
}
TeacherName是字符串,学生是学生列表
我需要这样做:给定一个用户名(user1),查询并返回所有文件,教师姓名是" user1"或者有一个名字为#34; user1"的学生。
我尝试了一些选项,但不能这样做。
我到目前为止找到的最接近的解决方案是使用.SelectMany()
,但我发现.SelectMany
会进行连接,并会复制返回结果。
这是我的疑问:
client.CreateDocumentQuery().SelectMany((x) => x.Students.Where(s=>s.Name == "user1" || x.TeacherName == "user1")
如果只有上面的示例文档在集合中,当我搜索用户名" Ben"时,将返回2条记录((结果数)*(学生数))。我必须在客户端删除副本,并且分页有点破碎。
是否可以发出单个查询来实现我的需求?
答案 0 :(得分:3)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/vendor.css') }}"/>
<link rel="stylesheet" href="{{ asset('build/style.css') }}"/>
<link rel="stylesheet" href="{{ asset('build/app.css') }}"/>
{% endblock %}
</head>
<body class="pal">
<div id="app">
<ingredient-search></ingredient-search>
</div>
{% block javascripts %}
<script src="{{ asset('build/manifest.js') }}"></script>
<script src="{{ asset('build/vendor.js') }}"></script>
<script src="{{ asset('build/style.js') }}"></script>
<script src="{{ asset('build/app.js') }}"></script>
{% endblock %}
</body>
</html>
实际上代码中的client.CreateDocumentQuery().SelectMany((x) => x.Students.Where(s=>s.Name == "user1" || x.TeacherName == "user1")
方法类似于下面的sql:
SelectMany
输出
SELECT c.id from c
join x in c.Students
where c.TeacherName ='Ben' or x.Name = 'Ben'
如果有加入,则会出现重复数据。据我所知,Azure Cosmos DB不支持自动删除重复数据(如传统数据库中的[
{
"id": "1"
},
{
"id": "1"
}
]
关键字)。
似乎无法在查询SQL级别中删除重复数据。
如果您不想在本地循环中处理查询结果集,我强烈建议您使用stored procedure处理Azure Cosmos DB中的结果数据,以释放当地的压力服务器
或者,如果您的数据不是太大,您可以直接在存储过程中完成查询。请参考以下js代码:
Distinct
更新答案:
我检查了Azure Cosmos DB pricing details。然后它没有表明存储过程比单个查询更昂贵。实际上,成本取决于// SAMPLE STORED PROCEDURE
function sample(idsArrayString,courses) {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM root r',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
var returnResult = [];
for(var i = 0;i<feed.length;i++){
var doc = feed[i];
if(doc.TeacherName == 'Ben'){
returnResult.push(feed[i]);
break;
}
var std = doc.Students;
for (var s in std) {
if(s.Name == 'Ben'){
returnResult.push(feed[i]);
break;
}
}
}
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
和Rus
取决于查询的复杂性和并发量等。
您可以参考R document。此外,您可以通过http请求标头知道RU费用:RuS
。请看这个有用的痕迹:
How to caculate the Azure Cosmos DB RU used in server side scripting
希望它对你有所帮助。