DocumentDB不受支持的查询

时间:2017-09-26 20:58:13

标签: c# linq azure-storage azure-cosmosdb

我尝试在IQueryable中使用字典,但是我收到运行时错误,我知道问题发生是因为实时IQueryable不熟悉那个对象,我尝试将IQueryable转换为IEnumerable,但是我的执行有问题查询。 愿有人能给我一个如何执行该功能的提示吗?

我有以下代码:

Dictionary<String, int> coursesType= new Dictionary<string, int>();      
var userQuery = _client.CreateDocumentQuery<ObjectModel.Student>(uriStudentCollection, options).
                    Where(x =>coursesType.ContainsKey(x.MainCourse) 
                    && !x.Courses.ContainsKey(requestCourse)).OrderBy(x => x.Grade).AsDocumentQuery();
                var feedResponse = await userQuery.ExecuteNextAsync<ObjectModel.Student>();

                foreach (var ad in feedResponse.AsEnumerable())
                {
                    results.Add(ad);
                }

更新状态:我还没有收到我的问题的答案

***更新:我添加了我的文档示例。

    {
    "id": "a5d7f123-80d5-5094-84fb-08c3bc4ccp972",
    "StudentName": "Philip",
"Courses": {
        "Math": {
            "id": "Math",
            "Grade": "98",
            "Place": "NYC"
}
},
"Rank":"AA"
}

更新号码3

我写了以下查询:

 SqlQuerySpec q = new SqlQuerySpec()
            {
                QueryText = "SELECT * FROM c WHERE (CONTAINS(LOWER(c[\"courseName\"]),@text) OR CONTAINS(LOWER(c[\"courseDescription\"]),@text) ) AND (udf.CourseContainsKey(c[\"Courses\"],@courseId)=false)",
                Parameters = new SqlParameterCollection()
                {
                    new SqlParameter("@text", text),
                     new SqlParameter("@courseId", courseId)
                }
            };

当我写这样的查询时,查询工作正常,但如果我将ORDER BY命令添加到查询中我收到空集....

&#34; SELECT * FROM c WHERE(CONTAINS(LOWER(c [\&#34; courseName \&#34;]),@ text)或CONTAINS(LOWER(c [\&#34; courseDescription \ &#34;]),@ text))AND(udf.CourseContainsKey(c [\&#34; Courses \&#34;],@ courseId)= false)ORDER BY c [\&#34; courseName \& #34;] ASC&#34;

由于

谢谢,

MAK

1 个答案:

答案 0 :(得分:1)

  

{“不支持方法'包含密钥'。”}

根据您的查询,您可以使用以下代码:

var userQuery = _client.CreateDocumentQuery<ObjectModel.Student>(uriStudentCollection, options).
                    Where(x =>coursesType.Keys.Contains(x.MainCourse) 
                    && !x.Courses.Keys.Contains(requestCourse)).OrderBy(x => x.Grade).AsDocumentQuery();

此外,如果启用跨分区查询,则会出现以下错误:

  

不支持使用TOP / ORDER BY或聚合函数进行交叉分区查询。

如果过滤器无法在CosmosDB端执行,我认为您需要从azure端拉出记录,然后在客户端进行过滤。此外,这是一个类似的问题,您可以参考here

<强>更新

示例文件:

{
  "id": "1ba6178b-7c22-440a-a4a2-25b4bc636b30",
  "MainCourse": "b",
  "Grade": "B",
  "Courses": {
    "a": "a",
    "b": "b"
  }
}

查询:

SELECT * FROM root WHERE ((root["MainCourse"] IN ("a", "b")) AND (root["Courses"]["a"] != null)) ORDER BY root["Grade"] ASC

修改您的C#代码,如下所示:

!x.Courses.Keys.Contains(requestCourse)

//To

x.Courses[requestCourse]==null

<强> UPDATE2:

为了过滤Courses属性中不包含的特定课程名称,我假设您可以使用User-defined functions,这里是代码段,您可以参考它:

udf.CourseContainsKey:

function CourseContainsKey (courses,courseName) { 
   if(courses==undefined||courseName==undefined)
   return false;

   return courses.hasOwnProperty(courseName);
}

<强>测试

enter image description here

<强> UPDATE3:

我没有找到使用UDF创建查询的更好方法,您可以按照以下代码创建文档查询:

var query = $"SELECT* FROM root WHERE (root[\"MainCourse\"] IN({String.Join(",", coursesType.Keys.Select(k=>$"\"{k}\"").ToArray())})) AND udf.CourseContainsKey(root[\"Courses\"],\"{requestCourse}\")=false ORDER BY root[\"Grade\"] ASC";
var items=client.CreateDocumentQuery<CourseSample>(UriFactory.CreateDocumentCollectionUri(DatabaseId, DocumentCollectionId), sqlExpression:query).ToList();