Запрос к Firestore для логического свойства в Asp. net Сбой ядра / пустельги в Linux Docker - PullRequest
0 голосов
/ 15 марта 2020

Это то, что работает локально в Asp. Net Core 2.0 с C# на IIS Express и эмуляторе Firestore. Я пытаюсь использовать ту же кодовую базу на GCP с ядром Asp. Net, работающим на Kestrel внутри Linux Контейнер в GCP (Kubernetes)

Я могу подтвердить, что это определено c для Firestore и укажите c для запросов с логическим свойством, только если другие запросы работают нормально.

        CollectionReference FoosRef = FirestoreDb.Collection(FooKind);
        Query query = FoosRef.WhereEqualTo("IsGoodFoo", true);
        // QuerySnapshot querySnapshot = await query.Offset(offset).GetSnapshotAsync();
        // Query query = FoosRef.WhereEqualTo("FooName", "p,ezbnR33GU_");
        QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
        DocumentSnapshot documentSnapshot = querySnapshot.Documents.FirstOrDefault();

Как вы можете видеть, прокомментированный код отлично работает в той же самой настройке, в то время как запрос к «IsGoodFoo» с истинными ошибками завершается. Я могу подтвердить, что данные в Firestore сохранены как логические, поскольку поиск «true» в интерфейсе Firestore не дает мне никаких результатов. (Запрос истинных работ в эмуляторе Firestore)

Поскольку это трудная задача sh, я также не вижу никаких журналов, записанных в StackDriver, нет идеи, где можно проверить журналы Kestrel или правильно отладить эту проблему.

1 Ответ

1 голос
/ 18 марта 2020

Проблема оказалась не в «запросе с использованием логического свойства», а в «попытке получить результаты запроса с примерно 200 000 результатов».

Есть несколько вариантов сделать это. Самый простой способ , когда в запросе все еще достаточно мало результатов , - использовать метод StreamAsync. Используя C# 8 (и версию 2.x API Google.Cloud.Firestore, которые поддерживают более новую версию IAsyncEnumerable<>), вы можете просто использовать такой код:

var stream = collection.WhereEqualTo("IsGoodFoo", true).StreamAsync();
await foreach (var document in stream)
{
    // Do whatever with the document
}

В моем тестировании (с результатом запроса 900K +), который истекает через минуту после извлечения ~ 210K элементов. Мне пока не ясно, ожидаемо это или нет.

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

int limit = 1000;
var query = collection.WhereEqualTo("IsGoodFoo", true).Limit(limit);

// Used to specify a cursor
DocumentSnapshot lastDocument = null;
while (true)
{
    var queryWithCursor = lastDocument is null ? query : query.StartAfter(lastDocument);
    var querySnapshot = await queryWithCursor.GetSnapshotAsync();
    foreach (var document in querySnapshot)
    {
        // Use the document
    }
    if (querySnapshot.Count != limit)
    {
        break;
    }
}

Обратите внимание, что, хотя вы можете указать Offset вместо использования курсора, это становится значительно менее эффективным, когда смещение очень велико.

...