Подтвердить что ты не робот

Подкомпоны запроса запроса Firestore

Я думал, что прочитал, что вы можете запросить подколлекции с новым Firebase Firestore, но я не вижу никаких примеров. Например, у меня есть настройка Firestore следующим образом:

  • Танцы [коллекция]
    • danceName
    • Песни [коллекция]
      • songName

Как я могу запросить "Найти все танцы, где songName ==" X ""

4b9b3361

Ответ 1

Обновление 2019-05-07

Сегодня мы выпустили запросы групп сбора, и они позволяют выполнять запросы по всем подколлекциям.

Так, например, в веб-SDK:

db.collectionGroup('Songs')
  .where('songName', '==', 'X')
  .get()

Это будет соответствовать документам в любой коллекции, где последняя часть пути коллекции - "Песни".

Ваш первоначальный вопрос был о поиске танцев, где songName == 'X', но это по-прежнему невозможно напрямую, однако, для каждой подходящей песни вы можете загрузить ее родителя.

Оригинальный ответ

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

Альтернативная структура на данный момент состоит в том, чтобы сделать песни коллекцией верхнего уровня и сделать так, чтобы танец песни стал частью свойства песни.

Ответ 2

ОБНОВЛЕНИЕ Теперь Firestore поддерживает массив-содержит

Наличие этих документов

    {danceName: 'Danca name 1', songName: ['Title1','Title2']}
    {danceName: 'Danca name 2', songName: ['Title3']}

сделай это так

collection("Dances")
    .where("songName", "array-contains", "Title1")
    .get()...

@Nelson.b.austin Так как у пожарного магазина этого еще нет, я предлагаю вам иметь плоскую структуру, что означает:

Dances = {
    danceName: 'Dance name 1',
    songName_Title1: true,
    songName_Title2: true,
    songName_Title3: false
}

Имея это таким образом, вы можете сделать это:

var songTitle = 'Title1';
var dances = db.collection("Dances");
var query = dances.where("songName_"+songTitle, "==", true);

Надеюсь, это поможет.

Ответ 3

Что делать, если вы храните песни как объект, а не как коллекцию? Каждый танец как, с песнями как поле: type Object (не коллекция)

{
  danceName: "My Dance",
  songs: {
    "aNameOfASong": true,
    "aNameOfAnotherSong": true,
  }
}

тогда вы можете запросить для всех танцев с помощью aNameOfASong:

db.collection('Dances')
  .where('songs.aNameOfASong', '==', true)
  .get()
  .then(function(querySnapshot) {
    querySnapshot.forEach(function(doc) {
      console.log(doc.id, " => ", doc.data());
    });
   })
   .catch(function(error) {
     console.log("Error getting documents: ", error);
    });

Ответ 4

ОБНОВЛЕНИЕ 2019

Firestore выпустили коллекционные групповые запросы. См. Ответ Gil выше или официальную документацию по запросам группы сбора


Предыдущий ответ

Как заявил Гил Гилберт, кажется, что запросы групп сбора в настоящее время находятся в разработке. В то же время, вероятно, лучше использовать коллекции корневого уровня и просто связывать эти коллекции, используя UID документа.

Для тех, кто еще не знает, у Джеффа Делани есть невероятные руководства и ресурсы для тех, кто работает с Firebase (и Angular) на AngularFirebase.

Firestore NoSQL реляционное моделирование данных - здесь он разбивает основы структурирования БД NoSQL и Firestore

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

Ответ 5

Ограничения запроса

Cloud Firestore не поддерживает следующие типы запросов:

  1. Запросы с фильтрами диапазона на разных полях.

  2. Отдельные запросы по нескольким коллекциям или вложенным коллекциям. Каждый запрос выполняется к одному набору документов. Для получения дополнительной информации о том, как ваша структура данных влияет на ваши запросы, см. Выбор структуры данных.

  3. Логические ИЛИ запросы. В этом случае вы должны создать отдельный запрос для каждого условия ИЛИ и объединить результаты запроса в вашем приложении.
  4. Запросы с условием! =. В этом случае вы должны разделить запрос на запрос больше, чем запрос и меньше. Например, хотя условие запроса where ("age", "! =", "30") не поддерживается, вы можете получить один и тот же набор результатов, объединив два запроса, один с предложением где ("age", "< "," 30 ") и один с предложением где (" age ","> ", 30).

Ответ 6

НОВОЕ ОБНОВЛЕНИЕ 8 июля 2019 г.:

db.collectionGroup('Songs')
  .where('songName', isEqualTo:'X')
  .get()

Ответ 7

Может быть лучше использовать плоскую структуру данных.
Документы определяют плюсы и минусы различных структур данных на этой странице.

В частности, об ограничениях структур с вложенными коллекциями:

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

В отличие от предполагаемых преимуществ плоской структуры данных:

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

Ответ 8

Вы всегда можете искать так:

this.key$ = new BehaviorSubject(null);

return this.key$.switchMap(key =>
  this.angFirestore
    .collection("dances").doc("danceName").collections("songs", ref =>
      ref
        .where("songName", "==", X)
    )
    .snapshotChanges()
    .map(actions => {
      if (actions.toString()) {
        return actions.map(a => {
          const data = a.payload.doc.data() as Dance;
          const id = a.payload.doc.id;
          return { id, ...data };
        });
      } else {
        return false;
      }
    })
);

Ответ 9

var songs = []    
db.collection('Dances')
      .where('songs.aNameOfASong', '==', true)
      .get()
      .then(function(querySnapshot) {
        var songLength = querySnapshot.size
        var i=0;
        querySnapshot.forEach(function(doc) {
           songs.push(doc.data())
           i ++;
           if(songLength===i){
                console.log(songs
           }
          console.log(doc.id, " => ", doc.data());
        });
       })
       .catch(function(error) {
         console.log("Error getting documents: ", error);
        });