Количество значений в базе данных

В моей структуре базы данных userDatabase/userID/Customers у меня есть два клиента. Например путь:

usersDatabase
    g8voYf1yoChnpmhkoPgtmO4FQT62 - (uid)
        Customers
            Tom Smith (customer with custom ID)
                -LDFZw1tca8KOrnqyyWH - (auto id of customer child)
                    Status of Service: "Open service"
            Ben Thomas (customer with custom ID)
                -LDFZw1tca8KOjgoenBN - (auto id of customer child)
                    Status of Service: "Open service"

Можно ли получить количество значений «Открытая услуга» от всех клиентов в моей базе данных? Теперь я знаю только, как распечатать это значение для каждого клиента ...

Мой код для получения значения из базы данных:

let userID = Auth.auth().currentUser?.uid
    let usersDatabaseRef = Database.database().reference().child("usersDatabase").child(userID!).child("Customers")
    usersDatabaseRef.observe(.value, with: { snapshot in
        var totalCustomerCount = 0
        for child in snapshot.children {
            let childSnap = child as! DataSnapshot
            let childrenRef = childSnap
            totalCustomerCount += Int(childrenRef.childrenCount)
            print("user \(childSnap.key) has \(childrenRef.childrenCount) customers")

            let userCustomerSnap = childSnap
            for customer in userCustomerSnap.children.allObjects as! [DataSnapshot] {
                let customerSnap = customer
                let dict = customerSnap.value as! [String: Any]

                let stat = dict["Status of Service"] as! String

                let myStatistic = PrintModel(status: stat)
                self.statistic.append(myStatistic)
                print("Statistic: \(String(describing: myStatistic.status))")
            }
        }
        print("... and there are \(totalCustomerCount) total customers")
    })

Например, мой журнал теперь показывает:

  1. пользователь Tom Smith имеет 1 клиентов
  2. Статистика: необязательно («Открытая услуга»)
  3. user Ben Thomas имеет 1 клиентов
  4. Статистика: необязательно («Открытая услуга»)

но хочу показать:

  1. Статистика: 2

Я отредактировал ваш вопрос и обновил структуру Firebase, так что посмотрите. Чтобы ответить на вопрос, конечно. Просто установите ссылку на your_firebase / customers и выполните Глубокий запрос, где serviceID / status_of_service равно Open service. Я бы посоветовал НЕ использовать имена клиентов в качестве имен узлов - лучше использовать их uid или, возможно, номер клиента. См. Также это

Jay 28.05.2018 00:17

Не могли бы вы показать мне свой ответ на примере кода?

Krzysztof Łowiec 28.05.2018 08:05

@ KrzysztofŁowiec Есть ли возможность изменить структуру базы данных? Что касается текущей структуры базы данных, вам нужно будет получать всех клиентов, как вы это делаете.

TheTiger 28.05.2018 14:04

@TheTiger В этой структуре нет ничего плохого, пока возвращаемые совпадения не превышают емкость устройства. Если это будет проблемой, можно использовать отдельный узел считать, если OP интересуется просто счетчиком, а не самими данными. например когда дочерний элемент добавлен или удален из узла клиентов, увеличьте / уменьшите отдельный узел счета на 1.

Jay 28.05.2018 20:06

@ KrzysztofŁowiec tom_smith является клиентом ИЛИ tom_smith может иметь несколько клиентов? Не могли бы вы расширить свой пример базы данных несколькими ключами и значениями. Тогда я попробую.

TheTiger 29.05.2018 06:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Разделите данные на их собственные узлы, денормализуя данные. Как это

users
   uid_0
     //some  info about this user
     open_service_calls
          auto_id_0: true
          auto_id_1: true
   uid_1
     //info about this user

customers
    customer_id_0
      customer_name: "Tom Smith"
      open_service_calls
          auto_id_0: true
    customer_id_1
      customer_name: "Ben Thomas"
      open_service_calls
          auto_id_1: true

service_calls
   auto_id_0
      customer_id: customer_id_0
      user_id: "uid_0"
      status_of_service: "Open service"
   auto_id_1
      customer_id: customer_id_1
      user_id: "uid_0"
      status_of_service: "Open service"

Это позволяет запрашивать клиентов, пользователей и решать этот вопрос, легко подсчитывая все открытые службы в базе данных для всех пользователей и клиентов; запросить service_calls / status_of_service для "Открытой службы"

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

Дополнительные узлы будут предлагать дополнительную гибкость запросов - хранение идентификатора пользователя в узле клиента позволит сверхлегкому запросу получить всех клиентов для конкретного пользователя, даже если у них нет запросов на обслуживание; все зависит от того, что вы хотите получить от Firebase.

--- Старый ответ ниже ---

Согласно моему комментарию к исходному вопросу, этот ответ включает использование глубокого запроса для запроса дочерний элемент дочернего узла клиентов. Идея здесь в том, что внутри пользовательского узла есть узел Customers, где каждый дочерний ключ - это имя клиента, а значение этого узла - пара ключ: значение строки «serviceID», а затем значение, которое может содержать другие дочерние узлы. о сервисе.

Важной частью глубокого запроса является сохранение последовательно именованных дочерних ключей, которые вы запрашиваете - в этом случае мы используем ключ serviceID, чтобы запрос мог правильно разрешить путь, а затем любой из дочерних узлов этого может быть запрашивается: status_of_service, возможно, отметка времени или даже местоположение службы

Первоначальная структура до ее изменения была

Customers
  Tom Cruise
      serviceID
         status_of_service: "Open service"
         //timestamp of service?
         //location of service?
         //other data about service we may need to query?
  Ben Smith
      serviceID:
         status_of_service: "Open service"

Обратите внимание, что для этого ответа self.ref = my firebase, поэтому клиенты являются прямым потомком этого пути.

let ref = self.ref.child("Customers")
let query = ref.queryOrdered(byChild: "serviceID/status_of_service")
               .queryEqual(toValue: "Open service")
query.observeSingleEvent(of: .value, with: { (snapshot) in 
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        print(snap)
    }
})

выход - два клиентских узла

   tom_smith
      serviceID
        status_of_service: "Open service"
   another_customer
      serviceID
        status_of_service: "Open service"

Думаю, serviceID имеет какое-то значение, а не текст serviceID.

TheTiger 28.05.2018 14:02

Но можно ли получить количество status_of_service, равное «Open service» (в данном случае 2)?

Krzysztof Łowiec 28.05.2018 16:12

@TheTiger serviceID - это ключ, а значение этого ключа - другая пара ключ: значение status_of_service: "Открыть услугу". serviceID должен быть этой строкой в ​​каждом узле, чтобы глубокий запрос работал. Другими словами, у него есть строка serviceID, поэтому Firebase знает путь для запроса Открытая служба - если бы этот текст был другим, это был бы другой путь, возможно, в каждом узле, и вы не могли бы выполнить глубокий запрос.

Jay 28.05.2018 20:00

@ KrzysztofŁowiec Конечно, просто распечатайте (snapshot.childrenCount). Это напечатает, сколько узлов было извлечено, которые соответствуют запросу Открытая служба

Jay 28.05.2018 20:02

Этот код не работает с моей базой данных. Что, если полный путь к базе данных - не Customers/Tom Smith/serviceID/Status of service: Open service, а usersDatabase/g8voYf1yoChnpmhkoPgtmO4FQT62/Customers/Tom Smith/-LDFZw1tca8KOrnqyyWH/Status of service: Open service?

Krzysztof Łowiec 28.05.2018 21:53

@ KrzysztofŁowiec Как видите, важно включить структуры Firebase в ваш первоначальный вопрос - иначе мы будем гадать. Можете ли вы удалить структуру в своем вопросе и заменить ее фрагментом вашей реальной структуры (пожалуйста, в виде текста, без изображений). Я предполагаю, что вы не сможете делать то, что вам нужно, с вашей текущей структурой, но давайте взглянем.

Jay 28.05.2018 22:27

@Jay Что вы скажете теперь об обновленной структуре БД? Я был прав насчет serviceID, он имеет какое-то значение, а не текст serviceID. Я также был прав относительно структуры db в моем вчерашнем комментарии, и теперь вы придумали изменить структуру db.

TheTiger 29.05.2018 15:23

@TheTiger Я не понимаю, почему вы разместили этот комментарий или считаете, что были «правы» в чем-то. В решении мой мы использовали Глубокий запрос для доступа к данным, хранящимся в узле. Чтобы это работало, имена путей должны быть согласованными - вот почему в моем первоначальном ответе мы использовали путь serviceID / status_of_service, где serviceID фактически является ключом, а это означает, что это будет буквальная строка serviceID. Вам следует взглянуть на документацию, которую я связал, так как это мощный инструмент для доступа к дочерним данным.

Jay 29.05.2018 20:27

@Тигр. Взгляните на раздел старого ответа, который я оставил в ответе. Первоначальное намерение состояло в том, чтобы сохранить узел с ключом serviceID согласованным для всех клиентов - поэтому глубокий запрос мог быть выполнен на любом из его дочерних узлов; статус службы, возможно, местоположение или диапазон отметок времени. Дело в том, что если вы хотите выполнить глубокий запрос, имя родительского ключа не может быть другим. Мы выбираем слово serviceID для этого примера, но с тем же успехом это может быть Сервисы или service_data или действительно любая строка - при условии, что она согласована. Если у вас есть альтернативный ответ, опубликуйте его!

Jay 29.05.2018 20:55

@Jay, но что, если я помещаю значение Статус службы каждого клиента в tableview (например: мои 4 ячейки в tableview показывают "Открытая служба", "Во время обслуживания", "Открытая служба", "Открытая служба"), а затем получаю количество ячеек содержание (пример: 3 («Открытая услуга) и 1 (« Во время обслуживания) ») - возможно ли это?

Krzysztof Łowiec 30.05.2018 09:31

@ KrzysztofŁowiec Я не думаю, что понимаю вопрос - вы не должны использовать элементы пользовательского интерфейса для получения подсчетов - которые должны быть получены из источника данных, поддерживающего tableView. Используя структуру, которую я предложил в своем ответе, должно быть довольно легко получить подсчеты любого вида услуг, открытых, находящихся в процессе, закрытых и т. д. Либо непосредственно из Firebase, либо из источника данных.

Jay 30.05.2018 17:13

Другие вопросы по теме