Получить объект JSON из массива JSON с помощью Cloudant - PullRequest
0 голосов
/ 29 ноября 2018

Я выполняю вызов API каждые 40 минут, чтобы получить информацию о текущем состоянии каждого автомобиля в автопарке.И каждый вызов добавляет один новый документ JSON в базу данных Cloudant.Каждый документ JSON определяет текущее состояние доступности для каждого автомобиля во многих местах во многих городах.В настоящее время в базе данных находится около 2200 документов JSON.Все документы JSON имеют одно поле с именем payload, которое содержит всю информацию;это большой массив объектов.Вместо того, чтобы извлекать весь массив объектов payload, я бы хотел получить только необходимую информацию с помощью запроса (то есть только один или несколько объектов этого массива).Однако у меня возникают трудности при составлении запроса, который приводит только к необходимым данным.

Ниже я объясню свою проблему более подробно: при сохранении документа JSON в Cloudant в параметре timestamp определяетсядокумент.Параметр _id определен равным этой отметке времени.Ниже я показываю упрощенную версию этих документов JSON:

 {
  "_id": "1540914946026",
  "_rev": "3-c1834c8a230cf772e41bbcb9cf6b682e",
  "timestamp": 1540914946026,
  "datetime": "2018-10-30 15:55:46",
  "payload": [
    {
      "cityName": "Abcoude",
      "locations": [
        {
          "address": "asterlaan 28",
          "geoPoint": {
            "latitude": 52.27312,
            "longitude": 4.96768
          },
          "cars": [
            {
              "mod": "BMW",
              "state": "FREE"
            }
          ]
        }
      ],
      "availableCars": 1,
      "occupiedCars": 0
    },
    {
      "cityName": "Alkmaar",
      "locations": [
        {
          "address": "Aert de Gelderlaan 14",
          "geoPoint": {
            "latitude": 52.63131,
            "longitude": 4.72329
          },
          "cars": [
            {
              "model": "Volswagen",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "Ardennenstraat 49",
          "geoPoint": {
            "latitude": 52.66721,
            "longitude": 4.76046
          },
          "cars": [
            {
              "mod": "BMW",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "Beneluxplein 7",
          "geoPoint": {
            "latitude": 52.65356,
            "longitude": 4.75817
          },
          "cars": [
            {
              "mod": "BMW",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "Dr. Schaepmankade 1",
          "geoPoint": {
            "latitude": 52.62595,
            "longitude": 4.75122
          },
          "cars": [
            {
              "mod": "BMW",
              "state": "OCCUPIED"
            }
          ]
        },
        {
          "address": "Kennemerstraatweg",
          "geoPoint": {
            "latitude": 52.62909,
            "longitude": 4.74226
          },
          "cars": [
            {
              "model": "Mercedes",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "NS Station Alkmaar Noord/Parkeerterrein Noord",
          "geoPoint": {
            "latitude": 52.64366,
            "longitude": 4.7627
          },
          "cars": [
            {
              "model": "Tesla",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "NS Station Alkmaar/Stationsweg 56",
          "geoPoint": {
            "latitude": 52.6371,
            "longitude": 4.73935
          },
          "cars": [
            {
              "model": "Tesla",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "Oude Hoeverweg",
          "geoPoint": {
            "latitude": 52.63943,
            "longitude": 4.72928
          },
          "cars": [
            {
              "model": "Tesla",
              "state": "FREE"
            }
          ]
        },
        {
          "address": "Parkeerterrein Wortelsteeg",
          "geoPoint": {
            "latitude": 52.63048,
            "longitude": 4.75487
          },
          "cars": [
            {
              "model": "Tesla",
              "state": "OCCUPIED"
            }
          ]
        },
        {
          "address": "Schoklandstraat 38",
          "geoPoint": {
            "latitude": 52.65812,
            "longitude": 4.75359
          },
          "cars": [
            {
              "model": "Volkswagen",
              "state": "FREE"
            }
          ]
        }
      ],
      "availableCars": 8,
      "occupiedCars": 2
    }
  ]
}

Как видите, поле payload представляет собой массив, содержащий несколько объектов (к сведению: каждый объект в этом массиве представляет один конкретный город: есть 1600 городов, поэтому 1600 вложенных объектов в массиве payload).Кроме того, внутри каждого из 1600 упомянутых объектов другие массивы и объекты снова вложены внутрь.Для всех объектов в массиве payload первое поле - cityName.

Кроме того, существует вложенный массив locations (внутри каждого из 1600 объектов массива payload), представляющий все адреса в определенном городе.Массив locations может иметь размер от 1 до 600, что означает от 1 до 600 вложенных объектов / адресов на город.Последние два поля во всех объектах массива payload: availableCars и occupiedCars.

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

  • Мне нужно указать начальную временную метку (или id) и конечную временную метку, в результате чего в JSON будут только документыэтот интервал.
  • Кроме того, мне нужно будет указать в документах JSON только один или несколько конкретных городов на cityName (есть 1600 городов), а затем получить количество доступных автомобилей availableCars и количество * 1038.* для этих городов.

Например, в этом упрощенном примере я хотел бы запросить информацию о состоянии (availableCars & оккупированных автомобилей) для города Алкмар из 1540914946026 (время эпохи)до сих пор.Я хотел бы получить следующий результат:

{
 "id":"1540914946026",
 "cityName":"Alkmaar",
 "availableCars":8,
 "occupiedCars":2
 }

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

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

1 Ответ

0 голосов
/ 14 декабря 2018

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

Если вы обнаруживаете, что попадаете в растущие массивы внутри документов для подмножеств данных, это является предупреждающим признаком того, что ваша модель данных не идеальна: документ теперь изменчив и растет (в результате возможны конфликты обновлений)и со временем доступ становится более громоздким, поскольку Cloudant не имеет механизма для извлечения только частей документа.Более того, Cloudant имеет ограничение (1M) на размер документа, поэтому, используя предложенную модель, вы, вероятно, также достигнете этого предела, и ваше приложение перестанет работать.

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

Правило большого пальца: небольшие документы.Неизменная модель, где это возможно.Документы группируют данные, которые либо изменяются, либо доступны как единое целое.

...