Как искать по части значения строкового поля в документе пожарного депо? - PullRequest
0 голосов
/ 19 января 2020

У меня есть пара документов в моем пожарном депо, и существует поданное имя, дата, которая является строкой и находится в каждом документе.

это структура поля из трех документы со значениями.

date:"2020.01.18" (document 1)
date: "2020.01.19" (document 2)
date: "2020.02.17" (document 3)

Я хочу запросить все документы с датой «2020.01» / «2020.02» (без учета дня. Выберите только данные из года и месяца)

Это то, что я пытался сделать

this.afs
      .collection("orders", ref => ref.where("date", '==', date)) //How should I change the condition ('==') in here to overcome with this problem.
      .valueChanges();
  }

Ответы [ 3 ]

2 голосов
/ 19 января 2020

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

Если вы ищете документы в январе или февраль 2020 года:

ref.where('date', '>=', '2020.01.01').where('date', '<', '2020.03.01')

Вы можете даже опустить дневную часть значений и получить тот же результат:

ref.where('date', '>=', '2020.01.').where('date', '<', '2020.03.')

Это потому что запросы Firestore выполняют сопоставление префиксов для операций диапазона над строками.

Еще один пример: получить все документы в 2020 году:

ref.where('date', '>=', '2020').where('date', '<', '2021')
1 голос
/ 19 января 2020

Решение № 1: Добавить дополнительное поле

Одним из возможных решений было бы добавление дополнительного поля к вашим документам, содержащее только год и месяц, следующим образом:

date:"2020.01.18" (document 1)
searchDate:"2020.01" (document 1)
date: "2020.01.19" (document 2)
searchDate:"2020.01" (document 2)
date: "2020.02.17" (document 3)
searchDate:"2020.02" (document 3)

Затем вы можете легко запросить это поле:

this.afs
      .collection("orders", ref => ref.where("searchDate", '==', "2020.02"))
      .valueChanges();
  }

Дублирование данных таким способом довольно классно c в No SQL World, чтобы упростить / оптимизировать обработку запросов. Он придерживается той же «философии», что и денормализация , которая также является классическим c подходом, как объясняется в этой статье о "методах моделирования данных" для баз данных № 1040 *


Решение № 2: Используйте определенный символ c Unicode для имитации SQL LIKE 'YYYY.MM.%'

Другим решением будет использование комбинации orderBy(), startAt() и endAt() (см. Документацию здесь ) вместе с символом \uf8ff следующим образом

var searchString = '2020.02.'   
this.afs
      .collection("orders", ref => ref.orderBy('searchDate')
      .startAt(searchString)
      .endAt(searchString + '\uf8ff'))
      .valueChanges();
  }

Фактически, символ \uf8ff следует за большинством обычных символов в Юникоде, поэтому запрос соответствует всем значениям, которые начинаются с searchString.


Обратите внимание, что в случае, если вы хотите построить запрос ИЛИ (т.е. все документы, которые имеют дата как «2020.01» ИЛИ как «2020.02»), это невозможно в Firestore, как объяснено в do c. Вам следует «создать отдельный запрос для каждого условия ИЛИ и объединить результаты запроса в вашем приложении».

0 голосов
/ 19 января 2020

то, как эти запросы работают по индексам, которые хранит Firestore, я не думаю, что это возможно, однако альтернативное решение - кэшировать значения в вашем локальном хранилище и передавать их клиенту

check к этой классной услуге ниже:

https://codereview.stackexchange.com/questions/235822/angular-fire-firestore-cached-service

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