При использовании Cosmos DB для MongoDB API (версия 3.4) следующий запрос на поиск в сочетании с сортировкой курсора метода работает некорректно:
db.test.find({"field1": "value1"}).sort({"field2": 1})
Ошибка возникает, если выполнены все следующие условия:
- политика индексирования по умолчанию была отброшена - независимо от того, были ли впоследствии созданы пользовательские индексы с использованием createIndex ().
- Запрос find () не возвращает никаких документов (Find (фильтр) .Count () == 0)
- Документ Sort, определяющий порядок сортировки, содержит только одно поле. Неважно, существует ли это поле или оно было проиндексировано. Использование двух полей в документе сортировки возвращает 0 совпадений, что является правильным поведением.
Ошибка также возникает, если выполнены все следующие условия:
- политики индексации по умолчанию были отброшены
- Запрос find () возвращает один или несколько документов
- Документ Sort содержит ровно одно поле. Это поле не было проиндексировано.
Сообщение об ошибке:
Путь к индексу, соответствующий указанному элементу упорядочения, исключен.
Неисправность возникает только при использовании CosmosDB, с нативным MongoDB (mongoDB Atlas, v4.0) она ведет себя правильно.
Используется Azure Cosmos DB для MongoDB API с проводным протоколом MongoDB 3.4 (функция предварительного просмотра). Проблема возникает как с драйвером MongoDB C # /. NET, так и с оболочкой mongo.
Кроме того, проблема возникает только с find (). Эквивалентный конвейер агрегации, содержащий $ match и $ sort, ведет себя корректно.
Воспроизведение
- Создайте учетную запись Azure Cosmos DB с помощью «Azure Cosmos DB для API MongoDB». Включите функцию предварительного просмотра MongoDB 3.4 (версия 3.2 не тестировалась).
- Создать новую базу данных
- Создание новой коллекции, определение ключа осколка
- Удалить политику индексирования по умолчанию (используя db.test.dropIndexes ())
- (Необязательно) Создание новых пользовательских индексов
- (Необязательно) Вставить документы
Выполнить команду в оболочке mongo (или эквивалентный код с драйвером mongoDB C # /. NET):
db.test.find({"field1": "value1"}).sort({"field2": 1})
Ожидаемый результат
Все документы, которые соответствуют критериям запроса. Если их нет, документы не возвращаются.
Фактический результат
Ошибка: ошибка: {
"_t": "OKMongoResponse",
«хорошо»: 0,
«код»: 2,
"errmsg": "Сообщение: {\" Ошибки \ ": [\" Путь индекса, соответствующий указанному элементу упорядочения, исключен. \ "]} \ r \ nActivityId: c50cc751-0000-0000-0000-000000000000, URI запроса: /apps/[...]/, RequestStats: \ r \ nRequestStartTime: 2019-07-11T08: 58: 48.9880813Z, RequestEndTime: 2019-07-11T08: 58: 49.0081101Z, Количество предпринятых регионов: 1 \ r \ nResponseTime: 2019-07-11T08: 58: 49.0081101Z, StoreResult: StorePhysicalAddress: rntbd: // [...] /, LSN: 359549, GlobalCommittedLsn: 359548, PartitionKeyRangeId: 0, IsValid: True, StatusCode: 400 , SubStatusCode: 0, RequestCharge: 1, ItemLSN: -1, SessionToken: -1 # 359549, UsingLocalLSN: True, TransportException: null, ResourceType: Document, OperationType: Query \ r \ n, SDK: Microsoft.Azure.Documents.Common /2.4.0.0 ", [...]
Обход
Добавление дополнительного «фиктивного» поля в документ сортировки предотвращает ошибку:
db.test.find({"field1": "value1"}).sort({"field2": 1, "dummyfield": 1}).count()
Обходной путь не является удовлетворительным. Это может фальсифицировать результат.
Я что-то не так делаю или Cosmos DB ведет себя здесь некорректно?