Как я могу достичь этого отношения «многие ко многим» в Firebase?

Я знаю, что Firebase не поддерживает JOIN между узлами (как SQL Server между таблицами), но это именно то, что мне нужно сделать. Вот моя ситуация:

У меня есть узел транзакций в Firebase, подобный этому (где я включаю название категории для каждой транзакции):

"transactions": 
{
    "-Jruazf35b9a_gAVmZBe": 
    {
    payee: "McDonalds", amount: "2.35", category: "Eating Out"
    }
    "-JruadR11b4a_aTVmZFi": 
    {
    payee: "Walmart", amount: "78.12", category: "Household"
    }
    "-Jruazf35b9a_AgvNWCq": 
    {
    payee: "CapitalOne", amount: "150.00", category: "Debt"
    }
    "-JryJF2c33ijbjbBc24p": 
    {
    payee: "FootLocker", amount: "107.54", category: "Personal Blow"
    }
    "-Jrz0T-aL61Vuw4SOqRb": 
    {
    payee: "Starbucks", amount: "2.88", category: "Eating Out"
    }
}

И у меня есть такой узел «Категории» (куда я включаю транзакции по каждой категории):

"categories": 
{
    "-Jruazf35b2a_gAVmZRy": 
    {
        categoryname: "Eating Out", 
        categorytype: "Expense"
    }
        "transactions": {
            "-Jruazf35b9a_AgvNWCq": {
                payee: "McDonalds", amount: "2.35"
               }
               .
               .
               .
        }
    }
}

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

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

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

Это очевидно из-за того, как я сохраняю данные. Поэтому моей первой логической реакцией было сохранить уникальный идентификатор категории в узле транзакций вместо имени категории. Однако это создает проблему, поскольку в моем маленьком мозгу SQL Server мне понадобится JOIN, чтобы я мог получить список транзакций, а также включить имя категории для каждой транзакции.

Как я могу структурировать свои данные, чтобы я мог:

  1. показать список транзакций, включая название категории (как это делается сегодня)
  2. разрешить пользователю переименовывать категорию и показывать изменения, отраженные для ВСЕХ транзакций (прошлых и будущих)
  3. показать список транзакций по каждой категории (я думаю, что текущий подход все еще будет действителен)

person Luis Cabrera    schedule 24.06.2015    source источник
comment
Возможен дубликат? stackoverflow.com/questions/25712083 / Да, я думаю, что лучше всего разделить категорию на отдельный тип. Транзакции должны быть связаны с идентификатором категории, а не с названием категории. И тогда вам не придется вести список транзакций в своей категории. Только метаданные категории, такие как идентификатор, имя и т. д.   -  person bbill    schedule 25.06.2015
comment
@bbill спасибо за быстрый ответ, и да, я согласен, что идентификатор категории должен быть связан с транзакциями. Читая сообщение в блоге Queries Part 1:..., мне все еще неясно, как подойти к решению, чтобы иметь возможность добиться чего-то подобного этому: Выбрать tran.payee, tran.amount, cat.categoryname из транзакций. тран оставил присоединиться к категориям cat на cat.categoryid = tran.categoryid   -  person Luis Cabrera    schedule 25.06.2015
comment
Объединение данных из двух списков по своей сути является медленной операцией, особенно в базах данных NoSQL. Я бы рекомендовал сохранить categoryName и добавить categoryId. Таким образом, вы можете показать текущий экран одним чтением, но также связать с категорией. О том, как работать с обновлением categoryName в каждой транзакции, см. «как записать денормализованные данные в firebase»> stackoverflow.com/questions/30693785/ и medium.com/@collardeau/es6-promises-with-firebase-76606f36c80c   -  person Frank van Puffelen    schedule 25.06.2015
comment
В качестве альтернативы: список категорий, вероятно, будет относительно небольшим. Таким образом, вы также можете предварительно загрузить его и выполнить поиск на стороне клиента во время итерации транзакций.   -  person Frank van Puffelen    schedule 25.06.2015
comment
@FrankvanPuffelen выполняет поиск на стороне клиента, пока вы выполняете итерацию транзакций, и добавление categoryId имеет смысл. Я попробую и вскоре отпишусь о результатах   -  person Luis Cabrera    schedule 25.06.2015


Ответы (1)


Объединение данных из двух списков по своей сути является медленной операцией, особенно в базах данных NoSQL.

Я бы рекомендовал сохранить имя категории и добавить идентификатор категории. Таким образом, вы можете показать текущий экран одним чтением, а также дать ссылку на категорию. Чтобы узнать, как работать с обновлением categoryName в каждой транзакции, см. для записи денормализованных данных в Firebase и https://medium.com/@collardeau/es6-promises-with-firebase-76606f36c80c.

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

person Frank van Puffelen    schedule 25.06.2015