Запрос БД Cosmos с использованием SQL работает при запуске в проводнике данных, но не при выполнении с C # DocumentClient - PullRequest
1 голос
/ 21 октября 2019

У меня есть запрос, который предназначен для подсчета количества свежих и устаревших документов определенного типа.

Учитывая тот факт, что я пытаюсь получить количество для более чем одного типа в одном запросе таместь хороший шанс, что запрос должен быть переписан и что новая версия работает, как и ожидалось, при использовании C #.

Запрос работает, если я запускаю в нем обозреватель данных Cosmos DB с помощью «New SQL Query», нопри выполнении того же запроса с использованием версий DocumentClient 2.2.2 и 2.8.1 (обновленных до последней версии) в пакете Microsoft.Azure.DocumentDB.Core это не так.

При наличии следующих документов:

Данные

[{
    "PartitionKey": "partition",
    "SomeKey": "foo",
    "Type": "DocumentType",
    "Value": "1",
    "StaleAfterThis": 101
},
{
    "PartitionKey": "partition",
    "SomeKey": "bar",
    "Type": "DocumentType",
    "Value": "2",
    "StaleAfterThis": 90
},
{
    "PartitionKey": "partition",
    "SomeKey": "bar",
    "Type": "DocumentType",
    "Value": "3",
    "StaleAfterThis": 500
},
{
    "PartitionKey": "partition",
    "SomeKey": "foo",
    "Type": "DocumentType",
    "Value": "4",
    "StaleAfterThis": 500
}]

И следующий запрос:

Запрос

SELECT
    SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleFooCount,
    SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'foo' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshFooCount,
    SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis < 100)) as StaleBarCount,
    SUM((SELECT VALUE Count(1) WHERE c.SomeKey = 'bar' AND c.PartitionKey = 'partition' AND c.StaleAfterThis >= 100)) as FreshBarCount
FROM c
WHERE
    c.Type = 'DocumentType' AND
    c.PartitionKey = 'partition'

При выполнении этого запроса в веб-редакторе запросов в Проводнике данных результат выглядит какожидается.

[
    {
        "StaleFooCount": 0,
        "FreshFooCount": 1,
        "StaleBarCount": 1,
        "FreshBarCount": 1
    }
]

Если я попробую один и тот же запрос, используя C #, DocumentClient все значения равны 0. Это имеет место как при возвращении динамического результата, так и типизированного.

C #типПример запроса d

var queryOptions = new FeedOptions { MaxItemCount = 1 };

var queryText =
    @"SELECT
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@foo' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey = '@bar' AND c.PartitionKey = '@partitionKey' AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
    FROM c
    WHERE
        c.Type = 'DocumentType' AND
        c.PartitionKey = '@partitionKey'";

var queryParameters = new SqlParameterCollection
{
    new SqlParameter("@partitionKey", "partition"),
    new SqlParameter("@foo", FooBarEnum.Foo.ToString()),
    new SqlParameter("@bar", FooBarEnum.Bar.ToString()),
    new SqlParameter("@staleAfterThis", 100)
};

var sqlQuerySpec = new SqlQuerySpec(queryText, queryParameters);

var query = _client.CreateDocumentQuery<TempResult>(_collectionLink, sqlQuerySpec, queryOptions).AsDocumentQuery();

var totalStaleDocuments = new TempResult();

while (query.HasMoreResults)
{
    foreach (var result in await query.ExecuteNextAsync<TempResult>())
    {
        totalStaleDocuments.FreshFooCount += result.FreshFooCount;
        totalStaleDocuments.StaleFooCount += result.StaleFooCount;
        totalStaleDocuments.FreshBarCount += result.FreshBarCount;
        totalStaleDocuments.StaleBarCount += result.StaleBarCount;
    }
}

public class TempResult
{
    public int StaleFooCount { get; set; }
    public int FreshFooCount { get; set; }
    public int StaleBarCount { get; set; }
    public int FreshBarCount { get; set; }
}

Ожидаемый результат:

[
    {
        "StaleFooCount": 0,
        "FreshFooCount": 1,
        "StaleBarCount": 1,
        "FreshBarCount": 1
    }
]

Результат при выполнении запроса с использованием C #:

[
    {
        "StaleFooCount": 0,
        "FreshFooCount": 0,
        "StaleBarCount": 0,
        "FreshBarCount": 0
    }
]

1 Ответ

0 голосов
/ 21 октября 2019

Ваш запрос C # не совпадает. В своем запросе на портале вы делаете c.SomeKey = 'foo', а в C # вы делаете c.Type = '@foo'

И, наконец, удалите ' из параметров запроса, например, так:

 var queryText =
            @"SELECT
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey  = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleFooCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey  = @foo AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshFooCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey  = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis < @staleAfterThis)) as StaleBarCount,
        SUM((SELECT VALUE Count(1) WHERE c.SomeKey  = @bar AND c.PartitionKey = @partitionKey AND c.StaleAfterThis >= @staleAfterThis)) as FreshBarCount
    FROM c
    WHERE
        c.Type = 'DocumentType' AND
        c.PartitionKey = @partitionKey";
...