Правильный способ добавления индекса в структуру вложенной базы данных в реальном времени - PullRequest
0 голосов
/ 14 ноября 2018

Структура базы данных выглядит следующим образом:

my-db
    |
    Users
        |
        CreatedAt: "SOME_VALUE"
        |
        Email: "SOME_EMAIL"
        |
        Mailboxes
                |
                445566
                    |
                    Address: "My address 1"
                    |
                    Status: Active
                |
                112233
                    |
                    Address: "My address 2"
                    |
                    Status: Active

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

db.ref('/Users')
    .orderByChild('mailboxes/' + mailboxId + '/status')
    .equalTo('Active')
    .once("value", function(snapshot){
      snapshot.forEach(function(childSnapshot){
        // GET SPECIFIC USER DATA FROM childSnapshot
      })
    })

Пока все работает нормально, но в журнале функций Firebase появляется предупреждение об ошибке:

@ firebase / database: FIREBASE WARNING: Использование неопределенного индекса. Ваш данные будут загружены и отфильтрованы на клиенте. Рассмотреть возможность добавления ".indexOn": "mailboxes / 445566 / status" в / Users к вашим правилам безопасности для лучшей производительности.

Я попытался добавить индекс в файл правил:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      "$userid": {
        "mailboxes": {
          "$mailboxid": {
            ".indexOn": ["status"]
            } 
        }
      }
    }
  }
}

но все равно безуспешно. Теперь мне интересно, что здесь не так.

1 Ответ

0 голосов
/ 14 ноября 2018

Индекс должен быть определен в месте, где вы выполняете запрос. Таким образом, поскольку вы выполняете запрос на /Users, именно здесь нужно определить индекс. Как говорится в сообщении об ошибке:

{
  "rules": {
    ".read": true,
    ".write": true,
    "users": {
      ".indexOn": "mailboxes/445566/status"
    }
  }
}

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

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

mailboxes: {
  "445566": {
    "Status": "Active",
    "user": "uid1"
  },
  "112233" {
    "Status": "Active",
    "user": "uid2"
  }
}

С указанной выше дополнительной структурой вы можете использовать этот индекс:

"mailboxes": {
  ".indexOn": "Status"
}

Затем вы запрашиваете этот /mailboxes, чтобы получить все почтовые ящики с определенным статусом, а затем определяете уникальных пользователей, которые будут отображаться там.

Также см .:

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