使用场景:
- 大数据量支持PB
- Nosql
多元索引功能类似es,但是个人用户不建议,因为有预留实例,每小时0.02元,因此,暂时放弃使用。
二级索引类似mysql,但是没有mysql好用。
<dependency>
<groupId>com.aliyun.fc.runtime</groupId>
<artifactId>fc-java-core</artifactId>
<version>1.3.0</version>
</dependency>
package com.alvin.service.impl;
import com.alicloud.openservices.tablestore.ClientException;
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.TableStoreException;
import com.alicloud.openservices.tablestore.model.*;
import com.alicloud.openservices.tablestore.model.search.SearchQuery;
import com.alicloud.openservices.tablestore.model.search.SearchRequest;
import com.alicloud.openservices.tablestore.model.search.SearchResponse;
import com.alicloud.openservices.tablestore.model.search.agg.AggregationBuilders;
import com.alicloud.openservices.tablestore.model.search.agg.CountAggregation;
import com.alicloud.openservices.tablestore.model.search.query.QueryBuilder;
import com.alicloud.openservices.tablestore.model.search.query.QueryBuilders;
import com.alvin.entity.Picture;
import com.alvin.entity.PictureVO;
import com.alvin.service.RandomPicService;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.List;
import java.util.Random;
/**
* @Description
* @Author 田云
* @Date 2020/3/19 21:20
* @Version 1.0
*/
@Service
public class RandomPicServiceImpl implements RandomPicService {
public static final String INDEX = "picture_index";
//static String endPoint = "123";
static String endPoint = "123";
static String accessKeyId = "123";
static String accessKeySecret = "123";
static String instanceName = "randomPic";
public static String TABLE_NAME = "picture";
public static SyncClient client = new SyncClient(endPoint, accessKeyId, accessKeySecret, instanceName);
/**
* 随机url
*
* @param type
* @return
*/
@Override
public String randomUrl(String type) {
QueryBuilder builder;
if (type == null) {
builder = QueryBuilders.matchAll();
} else {
builder = QueryBuilders.term(Picture.Fields.type, type);
}
CountAggregation.Builder count1 = AggregationBuilders.count("count", Picture.Fields.type);
/*
查询多少条数据
*/
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName(TABLE_NAME)
.indexName(INDEX)
.searchQuery(
SearchQuery.newBuilder()
.query(builder)
.limit(0)
.addAggregation(count1)
.build())
.build();
System.out.println(searchRequest);
SearchResponse resp = client.search(searchRequest);
//获取统计聚合的结果
long count = resp.getAggregationResults().getAsCountAggregationResult("count").getValue();
/*
再次查询
*/
int i = new Random().nextInt((int) count);
SearchRequest searchRequest2 = SearchRequest.newBuilder()
.tableName(TABLE_NAME)
.indexName("picture_index")
.addColumnsToGet(Picture.Fields.type)
.searchQuery(
SearchQuery.newBuilder()
.query(builder)
.limit(1)
.offset(i)
.addAggregation(count1)
.build())
.build();
SearchResponse resp2 = client.search(searchRequest2);
Row row = resp2.getRows().get(0);
return String.valueOf(row.getPrimaryKey().getPrimaryKeyColumn("url").getValue());
}
private Picture getPicture(Row row) {
return Picture.builder()
.url(String.valueOf(row.getPrimaryKey().getPrimaryKeyColumn("url").getValue()))
.type(String.valueOf(row.getColumns()[0].getValue()))
.build();
}
@Override
public void inserts(PictureVO pictureVO) {
BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();
for (String url : pictureVO.getUrls()) {
//描述主键信息
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(Picture.Fields.url, PrimaryKeyValue.fromString(url));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);
//描述属性信息
rowPutChange.addColumn(new Column(Picture.Fields.type, ColumnValue.fromString(pictureVO.getType())));
batchWriteRowRequest.addRowChange(rowPutChange);
}
batchWrite(batchWriteRowRequest);
}
@Override
public void deletes(PictureVO pictureVO) {
BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();
for (String url : pictureVO.getUrls()) {
//描述主键信息
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(Picture.Fields.url, PrimaryKeyValue.fromString(url));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowDeleteChange rowPutChange = new RowDeleteChange(TABLE_NAME, primaryKey);
batchWriteRowRequest.addRowChange(rowPutChange);
}
batchWrite(batchWriteRowRequest);
}
@Override
public Picture queryByUrl(String url) {
// 构造主键
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(Picture.Fields.url, PrimaryKeyValue.fromString(url));
PrimaryKey primaryKey = primaryKeyBuilder.build();
// 读一行
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey);
// 设置读取最新版本
criteria.setMaxVersions(1);
criteria.addColumnsToGet(Picture.Fields.type);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
System.out.println("读取完毕,结果为: ");
System.out.println(row);
return getPicture(row);
}
private void batchWrite(BatchWriteRowRequest batchWriteRowRequest) {
BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest);
System.out.println("是否全部成功:" + response.isAllSucceed());
if (!response.isAllSucceed()) {
for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) {
System.out.println("失败的行:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey());
System.out.println("失败原因:" + rowResult.getError());
}
/**
* 可以通过createRequestForRetry方法再构造一个请求对失败的行进行重试。这里只给出构造重试请求的部分。
* 推荐的重试方法是使用SDK的自定义重试策略功能,支持对batch操作的部分行错误进行重试。设定重试策略后,调用接口处即不需要增加重试代码。
*/
BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows());
}
}
/**
* 导入数据
*
* @param args
*/
public static void main(String[] args) throws Exception {
//ExportData("out.txt");
//importData("out.txt");
}
public static void importData(String path) throws IOException {
List<String> strings = FileUtils.readLines(new File(path), "utf-8");
for (String string : strings) {
String[] split = string.split("\t");
if (split.length != 2) {
continue;
}
//描述主键信息
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(Picture.Fields.url, PrimaryKeyValue.fromString(split[0]));
PrimaryKey primaryKey = primaryKeyBuilder.build();
RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);
//描述属性信息
rowPutChange.addColumn(new Column(Picture.Fields.type, ColumnValue.fromString(split[1])));
//添加新数据到表格
try {
client.putRow(new PutRowRequest(rowPutChange));
System.out.println("添加数据成功。");
} catch (TableStoreException e) {
System.err.println("操作失败,详情:" + e.getMessage());
System.err.println("Request ID:" + e.getRequestId());
} catch (ClientException e) {
System.err.println("请求失败,详情:" + e.getMessage());
}
}
System.out.println("ok");
}
public static void ExportData(String path) throws Exception{
SearchRequest searchRequest2 = SearchRequest.newBuilder()
.tableName(TABLE_NAME)
.indexName("picture_index")
.addColumnsToGet(Picture.Fields.type)
.searchQuery(
SearchQuery.newBuilder()
.query(QueryBuilders.matchAll())
.limit(100)
.offset(0)
.build())
.build();
SearchResponse resp2 = client.search(searchRequest2);
List<Row> rows = resp2.getRows();
BufferedWriter bw = null;
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));
for (Row row : rows) {
Picture picture = new RandomPicServiceImpl().getPicture(row);
bw.write(picture.getUrl() + "\t" + picture.getType() + System.lineSeparator());
}
bw.close();
System.out.println("ok");
}
}