数据库分区
IBM® Cloudant® for IBM Cloud® 支持两种类型的数据库:
- 分区
- 未分区
分区数据库提供重要的性能和成本优势,但是需要您指定数据的逻辑分区。 以下文本中更详细地描述了此过程。
或者,也可以创建一个非分区数据库。 这种类型的 数据库可能更容易操作,因为无需定义分区方案,但只能创建全局二级索引。
IBM Cloudant 强烈建议您使用分区数据库,以实现最佳长期数据库性能,其中数据模型允许对文档进行逻辑分区。
您可以在创建数据库时决定是否进行分区。 创建数据库时 创建数据库时,使用 partitioned
查询字符串参数设置数据库是否分区。 数据库是否分区。 partitioned
的默认值为 false
、 以保持与早期版本的兼容性。
无法更改现有数据库的分区类型。
数据库分片
在阅读本文档之前,您必须了解 IBM Cloudant中的 分片概念。
未分区数据库
A non-partitioned database is the older type of IBM Cloudant database, and the one that is familiar if you used CouchDB or IBM Cloudant previously.
在未分区数据库中,文档根据其文档标识的变换,以任意方式分发到分片中。 因此,文件的 ID 与它最终所在的分片之间并不存在真正的关系。 文件 具有相似文档 ID 的文档不太可能被放在同一个分片上。
未分区数据库仅提供全局查询,后文将对此进行更详细的描述。
分区数据库
分区数据库是最新的 IBM Cloudant 数据库类型。 在分区数据库中,文档通过使用分区键组成逻辑分区。 分区键。 分区键是分区数据库中文档 ID 的一部分。 分区数据库中文档 ID 的一部分。 所有文档分配给一个分区,通常会为许多文档指定相同的分区键。 分区的主 分区的主 JSON 数据及其索引最终会被集中在一起,这意味着数据库可以更高效地 更高效地查询分区内的数据。
分区数据库同时提供分区查询和全局查询。 分区查询利用数据库集群中的数据布局,以提供更高、更可缩放的查询性能。 分区 查询通常也比全局查询便宜。
由于分区数据库同时具备全局和分区 查询的优势,IBM Cloudant建议新应用利用这些优势。
什么是好的分区键?
如果您正在考虑使用IBM Cloudant 的新分区数据库功能,那么 那么分区密钥的选择就非常重要。 分区键必须具备以下特点:
- 许多值 - 大量小分区优于几个个大分区。 一百万个分区完全没问题,但每个分区的总大小要保持在 10 GB 以下。
- 无热点 - 避免将系统设计为使一个分区处理很高比例的工作负载。 如果各分区的工作分布均匀,数据库的运行就会更加流畅。
- 重复 - 如果每个分区键都是唯一的,则每个分区只存在一个文档。 要充分利用分区数据库,每个分区必须有多个文档,即在逻辑上属于同一个分区的文档。
让我们看一些用例,并了解好与不好的分区键是什么样的。
用例 | 描述 | 分区键 | 有效性 |
---|---|---|---|
电子商务系统 - 订单 | 每个订单一个文档 | order_id |
中性--每个分区只有一个文档,但没有分区查询的优势。 |
电子商务系统 - 订单 | 每个订单一个文档 | user_id |
很好 - 用户的所有订单都保存在一起。 |
电子商务系统 - 订单 | 每个订单一个文档 | status |
糟糕 - 按少数几个状态值(临时、已付款、已退款、已取消)对订单进行分组,会产生过多过大的分区。 |
博客平台 | 每个博客帖子一个文档 | author_id |
很好--如果有很多作者参与的话。 易于查询每个作者的帖子。 |
IOT - 传感器读数 | 每个读数一个文档 | device_id |
很好--如果有许多设备,确保一个设备不会比其他设备产生更多的读数。 |
IOT - 传感器读数 | 每个读数一个文档 | date |
坏 - 当前读数导致当前日期分区出现“热点”。 |
在某些用例中,分区密钥没有可行的选择。 在这种情况下,非分区数据库可能是最佳选择。 选择。 例如,存储电子邮件地址、密码哈希值和最后登录日期的用户数据库。 这些字段均不适合用作分区键,因此必须改为使用正常的未分区数据库。
查询
IBM Cloudant的查询类型可用于全局和分区查询。 另请参阅 的底层查询机制的简要概述。 的查询机制。
全局查询
您可以对以下索引类型进行全局查询:
- IBM Cloudant Query
- 视图
- 搜索
进行全局查询时,数据库必须对数据库中的所有数据执行分散收集操作。 数据库中的所有数据。 这一操作意味着向许多单独的 数据库服务器。 API 协调节点从所有这些服务器接收响应,然后合并这些响应以形成对客户机的单一响应。 这种响应 可能需要缓冲数据,并在数据需要排序等情况下延迟对客户端的响应。 例如,数据需要排序。
分区查询
您可以对以下索引类型进行分区查询:
- IBM Cloudant Query
- 视图
- 搜索
进行分区查询时,数据库只能查询单个分区内的数据。 单个分区内的数据。 一个分区的数据只驻留在一个分片中(有 三个副本)。 API 协调节点可直接向托管数据的服务器发出请求 请求,而无需合并来自多个服务器的响应。 多个服务器的响应。 API 协调节点也无需缓冲响应,因为它无需执行组合步骤。 因此,数据能更快地到达客户端。 更快。
随着数据库规模的扩大,分片的数量 也必须增加。 分片的增加会直接增加 在使用全局查询时,API 协调节点需要向托管数据的服务器进行的查询次数会直接增加。 查询次数。 但是,当您使用分区查询时,分区的数量对 API 协调节点需要联系的服务器数量没有影响。 对 API 协调节点需要联系的服务器数量没有影响。 由于 由于这个数字很小,增加数据量对查询延迟没有影响、 与全局查询不同。
分区数据库教程
您可以看到两个使用分区数据库的示例:
- 请阅读本博客文章中有关 分区数据库和Node.js的内容,包括如何创建分区数据库、搜索、视图和全局索引。
- 请阅读下面关于使用视图和
_all_docs
端点的示例。
示例 - 分区读取IoT数据
这种讨论是抽象的,让我们用一个例子来具体说明。 我们 以物联网领域为例,研究如何使用IBM Cloudant作为设备读数的历史记录。 设备读数的历史记录。 假设这些设备能提供道路或桥梁等基础设施上的传感器读数。 道路或桥梁等基础设施上的传感器读数。
审查以下假设:
- 成百上千的设备报告读数。
- 每个设备具有唯一标识。
- 每个基础设施项具有唯一标识。
- 设备不会在基础设施之间移动。
- 每个设备每 10 秒向 IBM Cloudant 写入一次读数。 该读数可能通过消息总线传送到IBM Cloudant。
在未分区数据库中,您可能允许 IBM Cloudant 生成文档标识。 另一个替代方法是按设备标识和记录时间戳记命名文档。
使用第二种方法,我们最终会得到如下示例的文档 ID:
device-123456:20181211T11:13:24.123456Z
该时间戳记也可以是纪元时间戳记。
这种方法通过使用分区索引,可以高效地查询每个设备的数据。 使用分区索引。 不过,可能需要使用全局索引来创建多个设备的 然而,全局索引可能需要用于创建多个设备的视图,例如,特定基础设施上的所有设备。 基础设施上的所有设备。
为了说明问题,让我们把情况复杂化一点。 假设应用程序主要需要读取特定基础设施的所有传感器数据,而不是单个设备的数据。 而不是单个设备。
在此应用程序中,按基础设施项目进行查询最为高效。 因此,按基础设施划分数据比按 ID 划分数据更有意义。 比按 ID 分区更有意义。 这种做法可以将特定基础设施的所有设备 作为一组进行有效查询。
对于罕见的按设备查询,您可以使用两种方法:
- 建立以设备为关键字的全局索引并进行查询。 这种方法更有效 如果对单个设备的查询很少且不重复,那么这种方法会更有效。
- 为基础架构建立全局索引映射设备,然后向基础架构分区发出分区 查询。 如果重复 如果要对特定设备进行重复查询,这种方法是可行的,因为可以缓存映射。 本应用采用了这种方法。
让我们来看看这种方法的效果如何。 让我们来看看四个查询:
- 一个基础设施项所有时间的读数。
- 一个基础设施项今天的读数。
- 一个特定设备所有时间的读数。
- 一个特定设备今天的读数。
创建数据库
要创建分区数据库,请将 true
作为 partitioned
参数传递给数据库创建请求:
本节的所有教程都将使用 readings
作为示例数据库。
curl -X PUT "$SERVICE_URL/readings?partitioned=true"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.Ok;
import com.ibm.cloud.cloudant.v1.model.PutDatabaseOptions;
Cloudant service = Cloudant.newInstance();
PutDatabaseOptions databaseOptions = new PutDatabaseOptions.Builder()
.db("readings")
.partitioned(true)
.build();
Ok response =
service.putDatabase(databaseOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.putDatabase({
db: 'readings',
partitioned: true
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.put_database(db='readings', partitioned=True).get_result()
print(response)
putDatabaseOptions := service.NewPutDatabaseOptions(
"readings",
)
putDatabaseOptions.SetPartitioned(true)
ok, response, err := service.PutDatabase(putDatabaseOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(ok, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
文档结构
首先,让我们定义一个简单的文档格式来使用:
{
"deviceID": "device-123456",
"infrastructureID": "bridge-9876",
"ts": "20181211T11:13:24.123456Z",
"reading": {
"temperature": {
"value": 12,
"unit": "c"
}
}
}
本文件使用基于基础设施的分区方案。 文件 ID 可能包括作为分区密钥的基础设施 ID,并包括作为文件密钥的设备和时间戳:
bridge-9876:device-123456-20181211T11:13:24.123456Z
创建索引
对于前面描述的查询,您需要两个索引:
- 将设备 ID 映射到基础设施 ID 的全局索引
- 读取分区索引映射设备 ID
创建全局视图索引
视图索引是执行设备标识到基础设施标识的简单映射的最高效方式。 要定义它,请上传一个设计文档,其中包含
options.partitioned
set to false
as this index is global. 而在 而在真正的 map
函数中,你需要对字段的存在进行更多的保护、 这份文件看起来会是这样的
{
"options": {
"partitioned": false
},
"views": {
"by-device": {
"map": "function(doc) { emit(doc.deviceID, doc.infrastructureID) }"
}
}
}
假定前一个文件为 ./view.json
,则使用以下命令将此文件上传到数据库:
curl -X PUT "$SERVICE_URL/readings/_design/infrastructure-mapping" -H 'Content-Type: application/json' --data @view.json
有关创建全局视图的更多语言示例,请参阅 存储视图定义 指南或 API 文档中的创建或修改设计文档部分。
创建分区的 IBM Cloudant Query 索引
要从分区返回特定设备的读数,可以使用 IBM Cloudant查询索引。 For this document, use POST
to _index
with an index definition that includes the partitioned
field set to true
.
对于查询索引定义,partitioned
字段不嵌套在 options
字段内 对象。
对于这些查询,您需要两个分区索引:
- 按时间戳记
- 按设备标识和时间戳记
按时间戳上传分区索引
使用此命令按时间戳将索引上传到数据库:
curl -X POST "$SERVICE_URL/readings/_index" -H 'Content-Type: application/json' --data '{
"index": {
"fields": [
{"ts": "asc"}
]
},
"name": "timestamped-readings",
"type": "json",
"partitioned": true
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.IndexDefinition;
import com.ibm.cloud.cloudant.v1.model.IndexField;
import com.ibm.cloud.cloudant.v1.model.IndexResult;
import com.ibm.cloud.cloudant.v1.model.PostIndexOptions;
Cloudant service = Cloudant.newInstance();
IndexField indexField = new IndexField.Builder()
.add("ts", "asc")
.build();
IndexDefinition index = new IndexDefinition.Builder()
.addFields(indexField)
.build();
PostIndexOptions indexOptions = new PostIndexOptions.Builder()
.db("readings")
.index(index)
.name("timestamped-readings")
.type("json")
.partitioned(true)
.build();
IndexResult response =
service.postIndex(indexOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const indexField = {
ts: 'asc'
}
const index = {
fields: [indexField]
}
service.postIndex({
db: 'readings',
name: 'timestamped-readings',
index: index,
type: 'json',
partitioned: true
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, IndexDefinition, IndexField
service = CloudantV1.new_instance()
index_field = IndexField(ts='asc')
index = IndexDefinition(
fields=[index_field]
)
response = service.post_index(
db='readings',
name='timestamped-readings',
index=index,
type='json',
partitioned=True
).get_result()
print(response)
var indexField cloudantv1.IndexField
indexField.SetProperty("ts", core.StringPtr("asc"))
postIndexOptions := service.NewPostIndexOptions(
"readings",
&cloudantv1.IndexDefinition{
Fields: []cloudantv1.IndexField{
indexField,
},
},
)
postIndexOptions.SetName("timestamped-readings")
postIndexOptions.SetType("json")
postIndexOptions.SetPartitioned(true)
indexResult, response, err := service.PostIndex(postIndexOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(indexResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/v5/core"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
按设备 ID 和时间戳上传分区索引
使用此命令按设备 ID 和时间戳将索引上传到数据库:
curl -X POST "$SERVICE_URL/readings/_index" -H 'Content-Type: application/json' --data '{
"index": {
"fields": [
{"deviceID": "asc"},
{"ts": "asc"}
]
},
"name": "deviceID-readings",
"type": "json",
"partitioned": true
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.IndexDefinition;
import com.ibm.cloud.cloudant.v1.model.IndexField;
import com.ibm.cloud.cloudant.v1.model.IndexResult;
import com.ibm.cloud.cloudant.v1.model.PostIndexOptions;
import java.util.Arrays;
Cloudant service = Cloudant.newInstance();
IndexField indexField1 = new IndexField.Builder()
.add("deviceID", "asc")
.build();
IndexField indexField2 = new IndexField.Builder()
.add("ts", "asc")
.build();
IndexDefinition index = new IndexDefinition.Builder()
.fields(Arrays.asList(indexField1, indexField2))
.build();
PostIndexOptions indexOptions = new PostIndexOptions.Builder()
.db("readings")
.index(index)
.name("deviceID-readings")
.type("json")
.partitioned(true)
.build();
IndexResult response =
service.postIndex(indexOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const indexField1 = {
deviceID: 'asc'
}
const indexField2 = {
ts: 'asc'
}
const index = {
fields: [indexField1, indexField2]
}
service.postIndex({
db: 'readings',
name: 'deviceID-readings',
index: index,
type: 'json',
partitioned: true
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, IndexDefinition, IndexField
service = CloudantV1.new_instance()
index_field1 = IndexField(deviceID='asc')
index_field2 = IndexField(ts='asc')
index = IndexDefinition(
fields=[index_field1, index_field2]
)
response = service.post_index(
db='readings',
name='deviceID-readings',
index=index,
type='json',
partitioned=True
).get_result()
print(response)
var indexField1 cloudantv1.IndexField
var indexField2 cloudantv1.IndexField
indexField1.SetProperty("deviceID", core.StringPtr("asc"))
indexField2.SetProperty("ts", core.StringPtr("asc"))
postIndexOptions := service.NewPostIndexOptions(
"readings",
&cloudantv1.IndexDefinition{
Fields: []cloudantv1.IndexField{
indexField1,
indexField2,
},
},
)
postIndexOptions.SetName("deviceID-readings")
postIndexOptions.SetType("json")
postIndexOptions.SetPartitioned(true)
indexResult, response, err := service.PostIndex(postIndexOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(indexResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/v5/core"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
进行查询
总的来说,你要进行四次查询:
- 一个基础设施项所有时间的读数。
- 一个基础设施项今天的读数。
- 一个特定设备所有时间的读数。
- 一个特定设备今天的读数。
查找一个基础设施项的所有读数
这些分区是基于基础结构的,因此可以使用 _all_docs
来表示分区。 分区。 例如,查询 bridge-9876
的所有读数 使用下面的命令来创建基础设施。
curl -X POST "$SERVICE_URL/readings/_partition/bridge-9876/_all_docs" -H 'Content-Type:
application/json' --data '{"include_docs": true}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.AllDocsResult;
import com.ibm.cloud.cloudant.v1.model.PostPartitionAllDocsOptions;
Cloudant service = Cloudant.newInstance();
PostPartitionAllDocsOptions allDocsOptions =
new PostPartitionAllDocsOptions.Builder()
.db("readings")
.partitionKey("bridge-9876")
.includeDocs(true)
.build();
AllDocsResult response =
service.postPartitionAllDocs(allDocsOptions).execute()
.getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
service.postPartitionAllDocs({
db: 'readings',
partitionKey: 'bridge-9876',
includeDocs: true
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_partition_all_docs(
db='readings',
partition_key='bridge-9876',
include_docs=True
).get_result()
print(response)
postPartitionAllDocsOptions := service.NewPostPartitionAllDocsOptions(
"readings",
"bridge-9876",
)
postPartitionAllDocsOptions.SetIncludeDocs(true)
allDocsResult, response, err := service.PostPartitionAllDocs(postPartitionAllDocsOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(allDocsResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
查找一个基础设施项的最近读数
该查询需要使用 分区 timestamped-readings
索引。 您可以 假设今天是 2018 年 12 月 13 日,您可以向分区发出查询,获取今天的读数。
向IBM Cloudant 发出请求时,分区会嵌入 HTTP 路径:
curl -X POST "$SERVICE_URL/readings/_partition/bridge-9876/_find" -H 'Content-Type:
application/json' --data '{
"selector": {
"ts": { "$gte": "20181213"}
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.FindResult;
import com.ibm.cloud.cloudant.v1.model.PostPartitionFindOptions;
import com.ibm.cloud.cloudant.v1.model.Selector;
import java.util.HashMap;
import java.util.Map;
Cloudant service = Cloudant.newInstance();
Map greaterThanOrEqualWithTs = new HashMap<>();
greaterThanOrEqualWithTs.put("$gte", "20181213");
Selector selector = new Selector();
selector.put("ts", greaterThanOrEqualWithTs);
PostPartitionFindOptions findOptions =
new PostPartitionFindOptions.Builder()
.db("readings")
.partitionKey("bridge-9876")
.selector(selector)
.build();
FindResult response =
service.postPartitionFind(findOptions).execute()
.getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
const selector: CloudantV1.Selector = {
ts: {'$gte': '20181213'}
}
service.postPartitionFind({
db: 'readings',
partitionKey: 'bridge-9876',
selector: selector
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_partition_find(
db='readings',
partition_key='bridge-9876',
selector={'ts': {'$gte': '20181213'}}
).get_result()
print(response)
selector := map[string]interface{}{
"ts": map[string]string{
"$gte": "20181213",
},
}
postPartitionFindOptions := service.NewPostPartitionFindOptions(
"readings",
"bridge-9876",
selector,
)
findResult, response, err := service.PostPartitionFind(postPartitionFindOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(findResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
查找设备的基础设施标识
下面的列表显示了我们尚未执行的两个查询:
- 一个特定设备所有时间的读数。
- 一个特定设备今天的读数。
对于这两个查询,您需要使用 全局 by-device
索引。 然后,您就可以查询各个分区的 读数。 虽然您可以使用全局索引来查询单个设备的读数 单个设备的读数,但从设备到基础设施 ID 的映射是高度 可缓存。 它从未改变! 使用这种方法,你可以在大多数请求中使用 更便宜、更高效的分区查询来处理大多数请求。
使用全局索引直接查询设备读数可能更高效 如果缓存设备到基础架构的映射对特定应用效果不佳的话 应用效果不佳时,使用全局索引直接查询设备读数可能会更有效。
要查找设备的相关分区,需要查询 by-device
视图、 发送设备 ID 作为键:
curl -X POST "$SERVICE_URL/readings/_design/infrastructure-mapping/_view/by-device' -H 'Content-Type: application/json' --data '{
"keys": ["device-123456"], "limit": 1
}'
有关显示查询全局视图的更多语言示例,请参阅 API 文档中的查询MapReduce视图。
上一条命令返回以下响应:
{
"total_rows": 5,
"offset": 0,
"rows": [
{
"id": "bridge-9876:device-123456-20181211T11:13:24.123456Z",
"key": "device-123456",
"value": "bridge-9876"
}
]
}
分区键位于包含行的 value
字段中:
bridge-9876
.
查询设备的所有结果
To get the results for a device, you issue a partition query for the device within the bridge-9876
partition. 将使用标准 IBM Cloudant Query 选择器,就像发出了全局查询一样。
向IBM Cloudant 发出请求时,分区会嵌入 HTTP 路径:
curl -X POST "$SERVICE_URL/readings/_partition/bridge-9876/_find" -H 'Content-Type:
application/json' --data '{
"selector": {
"deviceID": {
"$eq": "device-123456"
}
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.FindResult;
import com.ibm.cloud.cloudant.v1.model.PostPartitionFindOptions;
import com.ibm.cloud.cloudant.v1.model.Selector;
import java.util.HashMap;
import java.util.Map;
Cloudant service = Cloudant.newInstance();
Map equalWithDeviceID = new HashMap<>();
equalWithDeviceID.put("$eq", "device-123456");
Selector selector = new Selector();
selector.put("deviceID", equalWithDeviceID);
PostPartitionFindOptions findOptions =
new PostPartitionFindOptions.Builder()
.db("readings")
.partitionKey("bridge-9876")
.selector(selector)
.build();
FindResult response =
service.postPartitionFind(findOptions).execute()
.getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
const selector: CloudantV1.Selector = {
deviceID: {'$eq': 'device-123456'}
}
service.postPartitionFind({
db: 'readings',
partitionKey: 'bridge-9876',
selector: selector
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_partition_find(
db='readings',
partition_key='bridge-9876',
selector={'deviceID': {'$eq': 'device-123456'}}
).get_result()
print(response)
selector := map[string]interface{}{
"deviceID": map[string]string{
"$eq": "device-123456",
},
}
postPartitionFindOptions := service.NewPostPartitionFindOptions(
"readings",
"bridge-9876",
selector,
)
findResult, response, err := service.PostPartitionFind(postPartitionFindOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(findResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
查询设备的最近结果
To get the results for a device, you issue a partition query for the device within the bridge-9876
partition. 选择器只是略复杂一点,但仍与等效的全局查询相同。
查询最近的结果,假设今天是 2018 年 12 月 13 日
向 IBM Cloudant 发出请求时,分区嵌入在 HTTP 路径中:
curl -X POST "$SERVICE_URL/readings/_partition/bridge-9876/_find" -H 'Content-Type: application/json' --data '{
"selector": {
"deviceID": {
"$eq": "device-123456"
},
"ts": {
"$gte": "20181213"
}
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.FindResult;
import com.ibm.cloud.cloudant.v1.model.PostPartitionFindOptions;
import com.ibm.cloud.cloudant.v1.model.Selector;
import java.util.HashMap;
import java.util.Map;
Cloudant service = Cloudant.newInstance();
Map equalWithDeviceID = new HashMap<>();
equalWithDeviceID.put("$eq", "device-123456");
Map greaterThanOrEqualWithTs = new HashMap<>();
greaterThanOrEqualWithTs.put("$gte", "20181213");
Selector selector = new Selector();
selector.put("deviceID", equalWithDeviceID);
selector.put("ts", greaterThanOrEqualWithTs);
PostPartitionFindOptions findOptions =
new PostPartitionFindOptions.Builder()
.db("readings")
.partitionKey("bridge-9876")
.selector(selector)
.build();
FindResult response =
service.postPartitionFind(findOptions).execute()
.getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
const selector: CloudantV1.Selector = {
deviceID: {'$eq': 'device-123456'},
ts: {'$gte': '20181213'}
}
service.postPartitionFind({
db: 'readings',
partitionKey: 'bridge-9876',
selector: selector
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_partition_find(
db='readings',
partition_key='bridge-9876',
selector={
'deviceID': {'$eq': 'device-123456'},
'ts': {'$gte': '20181213'}
}
).get_result()
print(response)
selector := map[string]interface{}{
"deviceID": map[string]string{
"$eq": "device-123456",
},
"ts": map[string]string{
"$gte": "20181213",
},
}
postPartitionFindOptions := service.NewPostPartitionFindOptions(
"readings",
"bridge-9876",
selector,
)
findResult, response, err := service.PostPartitionFind(postPartitionFindOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(findResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。