Получить все документы только из одной известной коллекции - PullRequest
0 голосов
/ 18 мая 2018

У меня есть такая структура Firestore:

Category: {
    document1a: {
        name : "reptiles"
        animalsubcollection: {
            Document1b: {
                name: "snake"
                color: "white"
            }
            Document2b: {
                name: "lizard"
                color: "black"
            }
    document2a: {
        name : "mammals"
        animalsubcollection: {
            Document1b: {
                name: "monkey"
                color: "brown"
            }
            Document2b: {
                name: "cat"
                color: "white"
            }

Мне нужно перечислить эту информацию на одной странице, классифицируемой по категориям следующим образом:

Рептилии:

  • Змея: Белая
  • Ящерица: Черная

Млекопитающие:

  • Обезьяна: Коричневая
  • Кошка: Белая

Как и в примере выше, у меня всегда есть только одна известная подколлекция под названием animalsubcollection.

Как я могу добиться этого, используя AngularFire2 в Angular 5?

Если это не лучшая модель пожарного депо для такого рода информации, я могу изменить ее при необходимости.Я принимаю другие предложения для достижения того же результата.

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Предполагая, что у вас есть действительный массив JSON (тот, который вы опубликовали, недействителен) Вы можете сделать это очень простым способом, используя Angular.

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

как использовать библиотеку underscore.js в угловом 2

groupedSeriesNames = []
groupedSeries = []



categories =  Category: {
        document1a: {
            name : "reptiles"
            animalsubcollection: {
                Document1b: {
                    name: "snake"
                    color: "white"
                }
                Document2b: {
                    name: "lizard"
                    color: "black"
                }
        document2a: {
            name : "mammals"
            animalsubcollection: {
                Document1b: {
                    name: "monkey"
                    color: "brown"
                }
                Document2b: {
                    name: "cat"
                    color: "white"
                }
           .
           .
           .

Примерлучшей структуры данных:

{
        type: "reptiles",       
        name: "snake",
        color: "white"


    },
    {
        type: "reptiles",       
        name: "snake",
        color: "white"
    },
    {
        type: "mammals",        
        name: "snake",
        color: "white"
    }
}

ИЛИ

{
        name: "reptiles",
        animalsubcollection: {
            Document1b: {
                name: "snake",
                color: "white"
            }
        }
    },
    {
        name: "mammals",
        animalsubcollection: {
            Document1b: {
                name: "leion",
                color: "white"
            }
        }
    },
    {
        name: "mammals",
        animalsubcollection: {
            Document1b: {
                name: "papa",
                color: "white"
            }
        }
    }
this.groupedTypes = _.groupBy(this.categories, category=>category.name);
this.groupedSeriesNames = Object.keys(this.groupedSeries)

Certificate.serie станет их ключом, вы можете изменить сертификат.serie на любое другое свойство, такое как iden или что вам нужно

ваш html

<ul class="cert-result">
    <li *ngFor="let key of groupedSeriesNames">
      <table *ngFor="let category of groupedSeries[key]">
        <tr>
          <th>Name</th>
          <th>Color</th>
        </tr>
        <tr>
          <td>{{category.color}}</td>
          <td>{{category.name}}</td>
        </tr>
      </table>
    </li>
  </ul>

Код без подчеркивания (при условии, что json правильно структурирован)

function formatedCerts() {
      return categories.reduce((prev, now) => {
        if (!prev[now.name]) {
          prev[now.name] = [];
        }

        prev[now.name].push(now);
        return prev;
      }, {});
}
0 голосов
/ 21 мая 2018

Спасибо всем за предложения, но первоначальное предложение не нормализовало исходную модель базы данных, но нашло простое решение с использованием исходной модели.

Я знаю, что иногда проще просто создать 2Оу 3 новые нормализованные коллекции и решить проблему.С другой стороны, если есть возможность создать вложенную коллекцию, ей нужен способ запрашивать его данные в Angular em RxJS.

Итак, после 2 или 3 дней исследований я нашел способДля этого:

//necessary imports
import { Observable } from 'rxjs/observable';
import { combineLatest } from 'rxjs/observable/combineLatest';
import 'rxjs/add/operator/mergeMap';

// the observable for animals category collection
this.animals = this.afs
  .collection('Category')
  .snapshotChanges()
  .map(arr => {
    return arr.map(snap => {
      const categ = { id: snap.payload.doc.id, ...snap.payload.doc.data() };

      // the animalsubcollection, using the previous value as parameter
      return this.afs
        .collection(`Category/${categ.id}/animalsubcollection`)
        .valueChanges()
        .map(animalsub => {
          return { ...categ, animalSubs: animalsub };
        });
    });
  })
  .mergeMap(result => combineLatest(result));
  //thats the trick. Combine 2 observables into a new one.

В представлении:

<ion-card *ngFor="let animal of animals | async">
<p *ngFor="let as of animal.animalSubs">
     {{as.name}} - {{as.color}}
</p>

Надеюсь, это кому-нибудь поможет

0 голосов
/ 18 мая 2018

Я бы посоветовал вам нормализовать структуру данных.Вы можете следовать этому шаблону: https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape

В одном узле вашей структуры данных храните все имеющиеся у вас «животные».В остальном хранятся все «категории животных».В другом случае сохраняйте отношения между ними, связывая для каждой категории «ключ» животного.

{
    animals: {
        snake: { color: 'white '},
        lizard: { color: 'black' },
        monkey: { color: 'brown '}
    },
    categories: {
        reptiles: { description: 'something here about reptiles'},
        mammals:  { description: 'something here about mammals'}
    },
    animals_categories: {
        reptiles: ['snake', 'lizard'],
        mammals: ['monkey']
    }

}

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

...