使用Cloudant从JSON数组中检索JSON对象

使用Cloudant从JSON数组中检索JSON对象,json,nested,couchdb,cloudant,Json,Nested,Couchdb,Cloudant,我每40分钟进行一次API调用,以检索车队中每辆车的当前状态信息。每次调用都会向Cloudant数据库添加一个新的JSON文档。每个JSON文档定义了多个城市中多个地点的每辆车的当前可用性状态。数据库中目前大约有2200个JSON文档。所有JSON文档都有一个名为payload的字段,其中包含所有信息;它是一个大型的对象数组。我不想检索整个有效负载对象数组,而只想通过查询检索所需的信息(因此,仅检索该数组中的一个或多个对象)。然而,我很难起草一个只产生所需数据的查询 下面,我将更详细地解释我的问

我每40分钟进行一次API调用,以检索车队中每辆车的当前状态信息。每次调用都会向Cloudant数据库添加一个新的JSON文档。每个JSON文档定义了多个城市中多个地点的每辆车的当前可用性状态。数据库中目前大约有2200个JSON文档。所有JSON文档都有一个名为
payload
的字段,其中包含所有信息;它是一个大型的对象数组。我不想检索整个
有效负载
对象数组,而只想通过查询检索所需的信息(因此,仅检索该数组中的一个或多个对象)。然而,我很难起草一个只产生所需数据的查询

下面,我将更详细地解释我的问题: 将JSON文档保存到Cloudant时,文档中定义了时间戳。
\u 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个城市,因此
payload
数组中有1600个嵌套对象)。此外,在所提到的1600个对象中的每一个对象中,其他数组和对象也嵌套在其中。对于
payload
数组中的所有对象,第一个字段是
cityName

此外,还有一个嵌套的数组
locations
(在
有效负载
数组的1600个对象中的每个对象内),表示特定城市中的所有地址。
位置
数组的大小可以是1到600,这意味着每个城市有1到600个嵌套对象/地址。
payload
数组的所有对象中的最后两个字段是
availableCars
occupiedCars

我想要查询文档来查看在特定的时间间隔内特定城市有多少辆车可用和占用。为此:

  • 我必须指定一个开始时间戳(或
    id
    )和一个结束时间戳,结果只有这个间隔内的JSON文档
  • 此外,我需要在JSON文档中通过
    cityName
    指定一个或多个特定城市(共有1600个城市),然后获取这些城市的可用汽车数量
    availableCars
    和占用汽车数量
例如,在这个简化的示例中,我想查询从1540914946026(大纪元时间)到现在的阿尔克马尔市的状态信息(
availableCars
&`occupiedCars)。我希望得到以下结果:

{
 "id":"1540914946026",
 "cityName":"Alkmaar",
 "availableCars":8,
 "occupiedCars":2
 }
这只是一个例子,实际上,我希望能够查询其他城市,或者一起查询几个城市,然后获得每个城市的可用汽车数量
availableCars
和占用汽车数量
occupiedCars


有人能帮我定义一个查询和索引来获得上面的结果吗?我可以用cloudant查询来实现这一点吗?

您的数据模型没有发挥cloudant的优势。让每个文档组一起更改和访问数据。有效负载数组中的项目将更好地存储为离散文档

如果您发现自己接触到文档中不断增长的数组以获取数据子集,这是一个警告信号,表明您的数据模型并不理想:文档现在是可变的,并且不断增长(结果可能会导致更新冲突),随着时间的推移,访问变得更加麻烦,因为Cloudant没有只检索文档部分的机制。此外,Cloudant对文档大小有一个限制(1M),因此通过使用您提出的模型,您可能也会达到该限制,并且您的应用程序将停止工作

话虽如此,创建一个视图索引是有可能的,它允许您发送负载的每个组件,这将允许您查找每个城市的数据——但该解决方案仍然受到上述所有限制(文档模型是可变的,文档变大等)


经验法则:小文档。不可变的模型,如果可能的话。文档将更改或作为一个单元访问的数据分组。

您的数据模型没有发挥Cloudant的优势。让每个文档组一起更改和访问数据。有效负载数组中的项目将更好地存储为离散文档

如果您发现自己接触到文档中不断增长的数组以获取数据子集,这是一个警告信号,表明您的数据模型并不理想:文档现在是可变的,并且不断增长(结果可能会导致更新冲突),随着时间的推移,访问变得更加麻烦,因为Cloudant没有只检索文档部分的机制。此外,Cloudant对文档大小有一个限制(1M),因此通过使用您提出的模型,您可能也会达到该限制,并且您的应用程序将停止工作

话虽如此,创建一个视图索引是有可能的,它允许您发送负载的每个组件,这将允许您查找每个城市的数据——但该解决方案仍然受到上述所有限制(文档模型是可变的,文档变大等)


经验法则:小文档。不可变的模型,如果可能的话。文档对更改或作为一个单元访问的数据进行分组。

您是否试图查询
名称
许可证
、和
状态
,或者您想查询
名称
状态
,并让它返回
许可证
?@HypnicJerk我更改了上述文本和示例JSON文档;试着让我的问题更容易理解。因此,您在评论中引用的
name
license
字段不再存在。您是否正在尝试查询
name