Как использовать оператор array-contains с массивом объектов в Firestore?

# #javascript #firebase #react-native #google-cloud-firestore

Вопрос:

Итак, я хочу запросить некоторые данные из firestore.

это моя структура данных

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

итак, коллекция-это модули, тогда у меня теперь есть 2 документа, но их будет 75 или что-то в этом роде. Затем в этом документе я хочу получить конкретный документ с определенным идентификатором урока (в данном примере «2»). Как мне это запросить?

это то, что я пытаюсь, но это не работает для меня

     async function getModuleData() {
        let ModuleData = await firebase
            .firestore()
            .collection('Modules')
            .where('Lessons', 'array-contains', {LessonId: 2})
            .get()
            .then(snapshot => {
                snapshot.forEach(doc => {
                    console.log(doc.data())
                })
            });
   } getModuleData()
 

когда я это сделаю

     async function getModuleData() {
        let ModuleData = await firebase
            .firestore()
            .collection('Modules')
            .where('Title', '==', 'Leven vanuit verlossing')
            .get()
            .then(snapshot => {
                snapshot.forEach(doc => {
                    console.log(doc.data())
                })
            });
   } getModuleData()
 

это просто работает, так что это что-то с моим утверждением «где», я думаю?

Ответ №1:

Для использования array-contains с массивом объектов вам необходимо передать полный объект, который вы ищете в этом массиве.

Например,

 const lessonObj = {
  Title: "Leven vanuit verlossing",
  Description: "the desc",
  ...allTheOtherFieldsAsIs
}
firebase.firestore().collection("Modules").where("Lessons", "array-contains", lessonObj)
 

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

 const db = firebase.firestore()

const lessonsSnapshot = await db.collection("Modules")
                          .doc("moduleID")
                          .collection("Lessons")
                          .where("Title", "==", "Leven vanuit verlossing")
                          .get()

console.log(lessonsSnapshot.docs[0].data())
 

Комментарии:

1. Спасибо вам за ваш ответ. Да, может быть, это хорошая идея, чтобы разделить ее, но потом я получаю так много прочитанного😅

Ответ №2:

Как ответил Дхармарадж, array-contains оператор выполняет полное совпадение, поэтому он возвращает только документы, в которых массив содержит точное указанное вами значение.

Если вы хотите фильтровать только идентификаторы уроков, я бы рекомендовал добавлять дополнительное поле в каждый документ только с идентификаторами уроков. Затем вы можете отфильтровать это поле с помощью:

 firebase
        .firestore()
        .collection('Modules')
        .where('LessonsIDs', 'array-contains', 2)