![Maven Central Adds Sigstore Signature Validation](https://cdn.sanity.io/images/cgdhsj6q/production/7da3bc8a946cfb5df15d7fcf49767faedc72b483-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
tablestore-js
Advanced tools
表格存储(Table Store)是阿里云自研的 NoSQL 多模型数据库,提供海量结构化数据存储以及快速的查询和分析服务。表格存储的分布式存储和强大的索引引擎能够支持 PB 级存储、千万 TPS 以及毫秒级延迟的服务能力。
表格存储让我不需要关心运维层面的问题:可靠、安全、快速,并且非常灵活,无限无缝拓展,价格实惠;
引用官方,上面有更全面的说明:产品优势
自己在用表格存储的时候,觉得官方的 SDK 需要我关心很多与表格存储设计原理相关的事情,例如 Long 类型或搜索;
而我作为用户使用,更希望关注与自己业务相关的问题,当业务复杂度日益增长,更需要想办法节约成本;
于是当我插入一条数据进表格、或者搜索的时候,把一些自己不想关心的操作放到了公共函数中处理,代码更加简洁,如下:
// PUT
const res = await tj.row('sampleTable')
.rowExistenceExpectation(RowExistenceExpectation.IGNORE)
.returnType(ReturnType.Primarykey)
.put({
gid: 20013,
uid: 20013,
col1: '表格存储',
col2: '2',
col3: 3.1,
col4: -0.32,
col5: 123456789,
});
// Nested search
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.TERM_QUERY,
fieldName: 'Col_Nested.Sub_Col_Keyword',
value: 'hangzhou',
}]);
以上操作等同官方 SDK 的以下两个示例: 单行数据操作、 嵌套类型查询
当然这是一个取舍的问题,带来了便捷性的提升同时也舍弃了复杂的操作;例如我需要操作多版本数据时更常用官方的方式。
谨慎用于生产环境,推荐使用阿里云官方 SDK:aliyun-tablestore-nodejs-sdk
这个 SDK 是基于官方的 aliyun-tablestore-nodejs-sdk 做了一层简易的封装,具体的一些改变如下:
使用 JSDoc 注释规范维护代码;
在 getRow、search、batchGetRow 和 getRange 方法上,返回的数据新增 data 字段,该字段由 row 或 rows 生成:
与 primaryKey, attributeColumns 相关的传入都使用 key:value 方式传入,不用区分 primaryKey, attributeColumns;
使用链式调用,不用关心参数结构;
添加更多默认值;
在使用之前,请确保已开通 表格存储,并已完成密钥配置。
参考:初始化
const { TJ } = require('tablestore-js');
const tj = new TJ(config, tables, indexes);
config {
required string accessKeyId = 1
required string accessKeySecret = 2
required string endpoint = 3
required string instancename = 4
optional string stsToken = 5
optional string maxRetries = 6
}
tables {
required string tableName = 1
required string primaryKey = 2
}
indexes {
required string tableName = 1
required string primaryKey = 2
}
注意:参数的命名以 aliyun-tablestore-nodejs-sdk 为准
以下操作等同官方文档:
const res = await tj.table('sampleTable')
.capacityUnit({
read: 0,
write: 0,
})
.tableOptions({
timeToLive: -1,
maxVersions: 1,
})
.create;
const res = await tj.table('sampleTable')
.tableOptions({
maxVersions: 5,
})
.update;
const res = await tj.table('sampleTable').describe;
const res = await tj.table().list;
const res = await tj.table('sampleTable').delete;
以下操作等同官方文档:
const res = await tj.index('sampleTable').list;
const res = await tj.index('sampleTable')
.indexName('sampleIndex')
.create;
const res = await tj.index('sampleTable')
.indexName('sampleIndex')
.delete;
const res = await tj.index('sampleTable')
.indexName('sampleIndex')
.describe;
以下操作等同于官方文档 单行数据操作;
const { RowExistenceExpectation, ReturnType } = require('tablestore-js');
const res = await tj.row('sampleTable')
.rowExistenceExpectation(RowExistenceExpectation.IGNORE)
.returnType(ReturnType.Primarykey)
.put({
gid: 20013,
uid: 20013,
col1: '表格存储',
col2: '2',
col3: 3.1,
col4: -0.32,
col5: 123456789,
});
暂未实现 columnFilter 的参数组装;
const res = await tj.row('sampleTable')
.maxVersions(2)
.primaryKey({
gid: 20004,
uid: 20004,
})
.get();
const { RowExistenceExpectation } = require('tablestore-js');
const res = await tj.row('sampleTable')
.primaryKey({
gid: 9,
uid: 90,
})
.rowExistenceExpectation(RowExistenceExpectation.IGNORE)
.update({
PUT: {
col4: 4,
col5: '5',
col6: 6,
},
DELETE: {
col1: 1496826473186,
},
DELETE_ALL: ['col2'],
});
const { RowExistenceExpectation } = require('tablestore-js');
const res = await tj.row('sampleTable')
.rowExistenceExpectation(RowExistenceExpectation.IGNORE)
.primaryKey({
gid: 8,
uid: 80,
})
.delete;
以下操作等同于官方文档 多行数据操作;
以下仅对接口操作封装,文档中重试逻辑需要自行实现;
const res = await tj.batch.getRow([
{
tableName: 'sampleTable',
primaryKey: [
{ gid: 20013, uid: 20013 },
{ gid: 20015, uid: 20015 },
],
startColumn: 'col2',
endColumn: 'col4',
},
{
tableName: 'notExistTable',
primaryKey: [{ gid: 10001, uid: 10001 }],
},
]);
const res = await tj.batch.writeRow([{
tableName: 'sampleTable',
rows: [{
type: 'PUT',
rowExistenceExpectation: RowExistenceExpectation.IGNORE,
returnType: ReturnType.Primarykey,
rowChange: {
gid: 8,
uid: 80,
attrCol1: 'test1',
attrCol2: 'test2',
},
}],
}]);
const res = await tj.batch.getRange({
tableName: 'sampleTable',
direction: TableStore.Direction.FORWARD,
inclusiveStartPrimaryKey: {
gid: INF.MIN,
uid: INF.MIN,
},
exclusiveEndPrimaryKey: {
gid: INF.MAX,
uid: INF.MAX,
},
limit: 50,
});
以下操作等同官方文档:
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.TERM_QUERY,
fieldName: 'Col_Keyword',
value: 'hangzhou',
}]);
const { QueryType } = require('tablestore-js');
res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.TERMS_QUERY,
fieldName: 'Col_Keyword',
value: ['hangzhou', 'shanghai'],
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.returnFields(['Col_1', 'Col_2', 'Col_3'])
.query([{
queryType: QueryType.MATCH_ALL_QUERY,
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.MATCH_QUERY,
fieldName: 'Col_Keyword',
value: 'hangzhou',
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.MATCH_PHRASE_QUERY,
fieldName: 'Col_Text',
value: 'hangzhou shanghai',
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.PREFIX_QUERY,
fieldName: 'Col_Keyword',
value: 'hang',
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.RANGE_QUERY,
fieldName: 'Col_Long',
options: {
rangeFrom: 1,
includeLower: true,
rangeTo: 10,
includeUpper: false,
},
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.WILDCARD_QUERY,
fieldName: 'Col_Keyword',
value: 'table*e',
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.GEO_BOUNDING_BOX_QUERY,
fieldName: 'Col_GeoPoint',
options: {
topLeft: '10,0',
bottomRight: '0,10',
},
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.GEO_DISTANCE_QUERY,
fieldName: 'Col_GeoPoint',
options: {
centerPoint: '1,1',
distance: 10000,
},
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.GEO_POLYGON_QUERY,
fieldName: 'Col_GeoPoint',
options: {
points: ['0,0', '5,5', '5,0'],
},
}]);
const { QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.query([{
queryType: QueryType.TERM_QUERY,
fieldName: 'Col_Nested.Sub_Col_Keyword',
value: 'hangzhou',
}]);
const { BoolQueryType, QueryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.boolType(BoolQueryType.MUST_QUERIES)
.minimumShouldMatch(1)
.query([
{
queryType: QueryType.RANGE_QUERY,
fieldName: 'Col_Long',
options: {
rangeFrom: 3,
includeLower: true,
},
},
{
queryType: QueryType.TERM_QUERY,
fieldName: 'Col_Keyword',
value: 'hangzhou',
},
]);
const { SortOrder } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.scoreSort(SortOrder.ASC)
.query();
const { SortOrder } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.primaryKeySort(SortOrder.DESC)
.query();
const { SortOrder } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.fieldSort({
Col_Keyword: SortOrder.DESC,
Col_Long: SortOrder.DESC,
})
.query();
const { SortOrder } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.geoDistanceSort({
fieldName: 'Col_Geo_Point',
points: ['0,0'],
order: SortOrder.ASC,
})
.query();
const { queryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(90)
.limit(10)
.query([{
queryType: QueryType.MATCH_ALL_QUERY,
}]);
const { queryType } = require('tablestore-js');
const res = await tj.search(TABLE_NAME)
.indexName(INDEX_NAME)
.offset(0)
.limit(10)
.token(null)
.returnFields(['pic_tag', 'pic_description', 'time', 'pos'])
.query([{
queryType: QueryType.MATCH_ALL_QUERY,
}]);
FAQs
Aliyun TableStore SDK for JavaScript
We found that tablestore-js demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.