【问题标题】:DocumentDB unsupported queryDocumentDB 不支持的查询
【发布时间】:2018-03-08 05:23:15
【问题描述】:

我尝试在 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 命令添加到我收到空集的查询中......

"SELECT * FROM c WHERE (CONTAINS(LOWER(c[\"courseName\"]),@text) OR CONTAINS(LOWER(c[\"courseDescription\"]),@text) ) AND (udf. CourseContainsKey(c[\"Courses\"],@courseId)=false) 按 c[\"courseName\"] ASC" 排序

谢谢

谢谢,

马克

【问题讨论】:

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


    【解决方案1】:

    {“方法'ContainsKey'不受支持。”}

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

    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
    

    更新 2:

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

    udf.CourseContainsKey:

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

    测试:

    更新3:

    我还没有找到更好的方法来使用 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();
    

    【讨论】:

    • 嗨,谢谢你的回答,它解决了部分问题,我有两个问题 1.当我们使用 Keys.Contains 时,如果我们将它与 ContainsKey 进行比较,我们实际上会损害性能,我看到查询等于 IN (\"Collection\", \"mat\", \"physic\")。 2. !x.Courses.Keys.Contains(requestCourse) 不起作用,它返回一个空集(我确定查询不为空),有什么不同?查询是 ARRAY_CONTAINS(root[\"Courses\"][\"Keys\"], \"philo\")
    • 我检查了查询并更新了我的修改答案。
    • 嗨,它仍然没有解决它等于 (NOT (root[\"Courses\"][\"phil\"] != null) 的问题,它返回空集:-(
    • 嗨,它仍然不工作,我收到空集,查询转换为 AND (root[\"Courses\"][\"phil\"] = null),(我确定查询不是空集)。
    • x.Courses[requestCourse]==null 没有解决问题,我收到空集,linq 翻译成 SQL 查询:root[\"Courses\"][\"philo\"] =空
    猜你喜欢
    • 2021-11-08
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    相关资源
    最近更新 更多