Запит Firestore за діапазоном дат


77

Мені потрібна допомога для запиту довгої колекції з діапазоном дат. Див. Приклад документа нижче. Я хочу запитати поле startTime, використовуючи діапазон дат.

введіть тут опис зображення

введіть тут опис зображення

Відповіді:


129

Оскільки я dueDateзберігаю поле як "мітку часу" (а НЕ як рядок чи номер ) у Cloud Firestore, я зробив це, щоб отримати документи на рахунки-фактури із строком на 2017 рік:

let start = new Date('2017-01-01');
let end = new Date('2018-01-01');

this.afs.collection('invoices', ref => ref
  .where('dueDate', '>', start)
  .where('dueDate', '<', end)
);

ПРИМІТКА: dueDate поле було збережено у firebase з об’єктом Date (). наприклад:this.doc.dueDate = new Date('2017-12-25')


1
Якщо ви зробите знімок екрана свого камінника, чи можна звідти візуально визначити різницю між об’єктом дати чи рядком?
DauleDK

Так @DauleDK look: imgur.com/a/draQoТретє поле було заповнене js-об'єктом Date (), і воно було збережене як позначка часу (firebase зробив перетворення). І на зображенні ви побачите цей відміток часу у форматі UTC, АЛЕ я зберег його як об'єкт Date. І нарешті, щоб перевірити, чи це справді поле мітки часу, просто наведіть поле. У моєму випадку я бачу "Marca de tiempo", що означає "позначка часу".
Кейпі

3
Вау, це чудово - те, що неодмінно слід додати до документації запитів до firestore. У мене таке відчуття, що ми побачимо багато оновлень на консолі firebase-firestore. "Marce de tiempo" - найцінніший урок, отриманий сьогодні, gracias;)
DauleDK

2
друзі, я спробував це, але це нічого не повертає
Німер Фарахті

Крім того, якщо ви використовуєте додатковий запит еквівалентності '==', можливо, вам доведеться увімкнути складений індекс, найкращий спосіб це зробити, уловлюючи помилку, яка виведе посилання Firebase, за яким ви зможете перейти до автоматичного налаштування індекс. Мій запит виглядає так і потребував composite_index:.where('team_id', '==', teamId).where('time', '>=', start).where('time', '<=', end)
wdavies973

25

Ви можете зберегти об'єкт datetime як час Unix (секунди з 1 січня 1970 року). Тоді ви можете просто використати де виберіть так:

collectionRef.where("startTime", ">=", "1506816000").where("startTime", "<=", "1507593600")

До речі - для перетворення дати та часу в Unix у вашому додатку ви можете використовувати чудовий момент бібліотеки (якщо ви щось будуєте за допомогою js або node).


1
спасибі, але я вже маю дані з форматом дати, точно як доданий знімок екрана
Німер Фарахті

Гаразд. Відповідно до firebase datetime - це підтримуваний тип даних у firestore. Чи є startTime рядком або об’єктом datetime?
DauleDK

це об'єкт dateTime, це не рядок
Німер Фарахті

чи можете ви зробити знімок екрана з консолі firebase - де ви наведете мишу над вашим часом початку - щоб побачити, чи відображається дата і час,
DauleDK

додано до запитання новий знімок екрана, здається, час даних є міткою часу, коли я створюю поле за допомогою модуля моменту
Німер Фарахті

19
    var startfulldate = admin.firestore.Timestamp.fromDate(new Date(1556062581000));
    db.collection('mycollection')
      .where('start_time', '<=', startfulldate)
      .get()
      .then(snapshot => {              
            var jsonvalue: any[] = [];
            snapshot.forEach(docs => {
              jsonvalue.push(docs.data())
               })
                 res.send(jsonvalue);
                 return;
                }).catch( error => {
                    res.status(500).send(error)
                });

2
Чудово! Ти врятував мені життя, чоловіче. Я просто замінив admin.firestore на firebase.firestore, і він спрацював.
Fox5150


6

Для всіх, хто нещодавно використовував Firebase Firestore, існує різниця залежно від ваших налаштувань реалізації Firebase (залежно від версії Firebase).

Раніше Firestore зберігав Timestampяк Date, проте, як описано тут у документах, незабаром його замінить Timestampоб’єкт. Дивіться документацію Timestamp тут .

Ви вже можете примусити свою реалізацію, додавши параметр у своєму коді, щоб примусити Firebase використовувати об'єкти Timestamp замість Date, як у цьому прикладі:

var firebaseApp = firebase.initializeApp({
    apiKey: [APIKEY],
    authDomain: [FIREBASEAPPDOMAIN],
    projectId: [PROJECTID]
});

var firestore = firebase.firestore();
var settings = { timestampsInSnapshots: true }; // force Timestamp instead of Date
firestore.settings(settings);

1

Ті, хто, як і я, використовує PHP для доступу до Firestore, можуть зробити щось подібне:

$startTime = new DateTime('2020-05-23 00:00:00');
$endTime = new DateTime('2020-06-23 23:59:59');

$start = new Google\Cloud\Core\Timestamp($startTime);
$end = new Google\Cloud\Core\Timestamp($endTime);

// fb is a Google\Cloud\Firestore\FirestoreClient object
$this->query = $this->fb->collection('your_collection');

$aux = $this->query;
$aux = $aux->where('startTime', '<', $end);
$aux = $aux->where('startTime', '>', $start);

return $aux->documents();

Насолоджуйтесь


1

Рішення полягає у використанні Date.now (). Припиніть використовувати службу міток часу з Firebase, вам потрібно працювати з числовим значенням часу в мілісекундах, наприклад, наприклад: 1514271367000, натомість, якщо Firestore використовує 26.12.2017 1:56:07 GMT- 0500 (-05), не працюватиме . Прикладом запиту є:

this.fsService.afs.collection('chats/4bY1ZpOr1TPq8bFQ3bjS/finance/123+finance/12345'
          , ref => ref.orderBy('hour').startAt(1514184967000).endAt(1514271367000))
          .valueChanges().subscribe(data =>{
            this.mensajes = data;
          })

2
Чи добре, якщо Firestore зберігає Date.now () як числові дані? Я відчуваю, що побачення в деяких випадках краще саме завдяки цьому та легкості розуміння.
Теліон

Здається, це код бази даних Firebase у реальному часі (наприклад, він використовує startAtі endAt), а не код Firestore (який буде використовувати where, див. Тут ). Ці два подібні, але не однакові.
robsiemb

Який часовий пояс? Коли я визначаю число, чи слід переводити дату та час у GMT?
Csaba Toth

0

У програмі інтерфейсу це те, як мітки часу та дати Firebase можуть використовуватися для запитів та зберігання документів.

Використання дати Firestore


2
Привіт. Оскільки зовнішні посилання можуть бути корисними, будь ласка, вставте вміст своєї відповіді безпосередньо в SO.
Maciej Jureczko

0

Загальна функція пошуку документів у колекції за діапазоном дат конкретних полів:

public List<QueryDocumentSnapshot> findDocsByDateRange(String collection, 
                                                       String fieldStartDate,
                                                       String fieldEndDate,
                                                       Date startDate, 
                                                       Date endDate) {
    ApiFuture<QuerySnapshot> querySnapshot = fireStore()
                    .collection(collection)
                    .whereGreaterThanOrEqualTo(FieldPath.of(fieldStartDate), startDate)
                    .whereLessThanOrEqualTo(FieldPath.of(fieldEndDate), endDate)
                    .get();
    return querySnapshot.get().getDocuments();
}

Пакети:

import com.google.api.core.ApiFuture;
import com.google.cloud.firestore.DocumentSnapshot;
import com.google.cloud.firestore.FieldPath;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.QueryDocumentSnapshot;
import com.google.cloud.firestore.QuerySnapshot;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.