Firestore один запрос диапазона с заказом по другому полю - PullRequest
1 голос
/ 26 марта 2020

У меня есть следующая коллекция / документы

Location Collection
{
  "geoHash" : "wwscjrm3nu01",
  "timeStamp" : "March 25, 2020 at 1:07:38 PM UTC-4" 
}
{
  "geoHash" : "wwscjrm2wc2h",
  "timeStamp" : "March 25, 2020 at 2:07:38 PM UTC-4" 
}

замените GeoHashs # на приведенный выше пример

screenshot

Итак, я пытался сделать запрос диапазон этих GeoHashs с упорядочением их по метке времени "DES C", как показано ниже

    db.collection('location')
        .where('geoHash', '>=', 'wwkxt4kxmmvk')
        .where('geoHash', '<=', 'wwt4vsn22peq')
        .orderBy('timeStamp', 'DESC')
        .limit(15).get()

Это не сработало, пожалуйста, ошибка ниже

Error getting documents { Error: 3 INVALID_ARGUMENT: inequality filter property and first sort order must be the same: geoHash and timeStamp
at callErrorFromStatus (/srv/node_modules/@grpc/grpc-js/build/src/call.js:30:26)
at Http2CallStream.call.on (/srv/node_modules/@grpc/grpc-js/build/src/call.js:79:34)
at emitOne (events.js:121:20)
at Http2CallStream.emit (events.js:211:7)
at process.nextTick (/srv/node_modules/@grpc/grpc-js/build/src/call-stream.js:97:22)
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
code: 3,
details: 'inequality filter property and first sort order must be the 
same: geoHash and timeStamp',
metadata: Metadata { internalRepr: Map {}, options: {} } }

Что если У меня есть тысячи или миллионы документов в этой коллекции в месяц или день !? Кто-нибудь из вас сталкивается с этой проблемой и как лучше обойти ее?

Обновление 0.2

Я очень ценю вашу помощь и поддержку в решении этой проблемы. Я воспроизвел то, что вижу в своем конце.

В настоящее время я использую следующий запрос с Node js

       db.collection('locations')
        .where('geoHash', '>=', 'wwkxt4kxmmvk')
        .where('geoHash', '<=', 'wwt4vsn22peq')
        .orderBy('geoHash')
        .orderBy('timeStamp', 'desc')
        .limit(15).get().then(snapshot => {
          if (snapshot.empty) {
            console.log('No matching documents.');
          }
          snapshot.forEach(doc => {
            console.log(doc.data());
          });
        });

Ожидается фильтрация GeoHashs> Order GeoHashs> Order it по метке времени. Итак, конечные результаты предполагают упорядоченную временную метку, но я вижу следующее:

10:08:24.901 AM
   test
    { geoHash: 'wwscjrm3nu01',
      timeStamp: Timestamp { _seconds: 1585227600, _nanoseconds: 0 },
      post: '3' }
10:08:24.900 AM
   test
    { geoHash: 'wwscjrm3nu01',
      timeStamp: Timestamp { _seconds: 1585317000, _nanoseconds: 0 },
      post: '1' }
10:08:24.900 AM
   test
    { geoHash: 'wwscjrm2wc2h',
      timeStamp: Timestamp { _seconds: 1585314000, _nanoseconds: 0 },
      post: '2' }

Как вы видите в приведенном выше выводе, я исключаю, что Post 1> 2> 3 основан на timeStamp, но то, что я вижу выше, это Пост 2> 1> 3.

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

Итак, ваш рабочий запрос:

db.collection('locations')
  .orderBy("geoHash")
  .where('geoHash', '>=', range.lower)
  .where('geoHash', '<=', range.upper)
  .orderBy('timeStamp', 'DESC')
  .limit(15).get()

Из того, что я вижу, результаты, которые вы получаете, упорядочены по geoHash, и только затем по timeStamp. Итак: если два документа имеют одинаковое значение geoHash, они будут в порядке их значения timeStamp.

Это работает так, как задумано: когда вы выполняете запрос диапазона в поле, вы всегда сначала нужно заказать на этом поле. И так как вы впервые упорядочиваете это поле, результаты возвращаются в порядке этого поля.

Это присуще модели запросов Firestore, так что это может помочь узнать больше об этом. Гарантии производительности означают, что он всегда должен иметь возможность передавать результаты из базы данных, как только он найдет отправную точку для вашего запроса. Переупорядочение неизвестного числа результатов сделает невозможным постоянное выполнение этой гарантии производительности, поэтому не поддерживается операция.

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

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

Как вы можете видеть в документации publi c , выполняющей фильтр диапазона и первый порядок в разных полях, поскольку вы пытаетесь сделать это, он недопустим в Firestore.

Также, если вы попробуйте выполнить порядок умножения, помните, что вы собираетесь упорядочить все результаты по первому порядку, а затем, если есть похожие результаты, это будет упорядочено по второму порядку (в вашем случае вы сначала упорядочите все свои результаты с помощью geoHa sh, а затем по geoHa sh это будет отсортировано по дате, но только по аналогичным записям)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...