新增Maven依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置Mongodb連線資訊
spring:
data:
mongodb:
host: 10.30.29.246
port: 16030
authenticationDatabase: admin # 登入使用者的認證庫
database: nrdt
username: admin
password: QAZqaz@123321
通用服務(動態集合資料)
以下程式碼實現主要針對集合名稱和欄位都是未知的情況
@Slf4j
@Component
public class MongodbService {
@Autowired
private MongoTemplate mongoTemplate;
/**
* 新增集合(表)
*
* @param collName
*/
public void addCollection(String collName) {
Assert.notEmpty(collName, "collName");
boolean bol = mongoTemplate.collectionExists(collName);
if (!bol) {
mongoTemplate.createCollection(collName);
}
}
/**
* 刪除集合(表)
*
* @param collName
*/
public void dropCollection(String collName) {
Assert.notEmpty(collName, "collName");
boolean bol = mongoTemplate.collectionExists(collName);
if (bol) {
mongoTemplate.dropCollection(collName);
}
}
/**
* 清空集合資料
*
* @param collName
*/
public void clearCollection(String collName) {
Assert.notEmpty(collName, "collName");
boolean bol = mongoTemplate.collectionExists(collName);
if (bol) {
mongoTemplate.remove(new Query(), collName);
}
}
/**
* 修改欄位名稱
*
* @param collName
* @param oldName
* @param newName
* @return
*/
public boolean editField(String collName, String oldName, String newName) {
Assert.notEmpty(collName, "collName");
Assert.notEmpty(oldName, "oldName");
Assert.notEmpty(newName, "newName");
Query query = new Query();
Update update = new Update();
update.rename(oldName, newName);
UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
return result.wasAcknowledged();
}
/**
* 刪除指定列
*
* @param collName
* @param field
*/
public boolean dropField(String collName, String field) {
Assert.notEmpty(collName, "collName");
Assert.notEmpty(field, "field");
Query query = new Query();
Update update = new Update();
update.unset(field);
UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
return result.wasAcknowledged();
}
/**
* 新增欄位
*
* @param collName
* @param field
* @return
*/
public boolean addField(String collName, String field) {
Assert.notEmpty(collName, "collName");
Assert.notEmpty(field, "field");
Query query = new Query();
query.fields().include(field);
boolean bol = mongoTemplate.exists(query, collName);
if(!bol){
Update update = new Update();
update.set(field, 0.00d);
UpdateResult result = mongoTemplate.updateMulti(query, update, collName);
return result.wasAcknowledged();
}
return false;
}
/**
* 新增多個欄位
*
* @param collName
* @param fields
* @return
*/
public boolean addFields(String collName, List<String> fields) {
Assert.notEmpty(collName, "collName");
Assert.notNull(fields, "fields");
Update update = new Update();
boolean status = false;
for (String field : fields) {
Query query = new Query();
query.fields().include(field);
boolean bol = mongoTemplate.exists(query, collName);
if(!bol){
update.set(field, 0.00d);
status = true;
}
}
if(status){
UpdateResult result = mongoTemplate.updateMulti(new Query(), update, collName);
return result.wasAcknowledged();
} else {
return false;
}
}
/**
* 批次新增行資料
*
* @param collName
* @param jsonArray
*/
public void insert(String collName, JSONArray jsonArray) {
Assert.notEmpty(collName, "collName");
Assert.notNull(jsonArray, "jsonArray");
mongoTemplate.insert(jsonArray, collName);
}
/**
* 批次插入
* insert: 可以一次性插入一整個列表,不允許插入已存在的主鍵
* save: 需要遍歷列表,進行一條一條的資料插入,主鍵存在則是修改
* @param collName
* @param list
*/
public void insert(String collName, List<Document> list) {
Assert.notEmpty(collName, "collName");
Assert.notNull(list, "list");
mongoTemplate.insert(list, collName);
}
/**
* 修改行資料
*
* @param collName
*/
public void edit(String collName, JSONObject jsonObject) {
Assert.notEmpty(collName, "collName");
Assert.notNull(jsonObject, "jsonObject");
mongoTemplate.save(jsonObject, collName);
}
/**
* 刪除行資料
*
* @param collName
*/
public boolean remove(String collName, String[] ids) {
Assert.notEmpty(collName, "collName");
Assert.notNull(ids, "ids");
Query query = new Query(Criteria.where(MongoConstants.ID_COLUMN).in(ids));
DeleteResult result = mongoTemplate.remove(query, collName);
return result.wasAcknowledged();
}
/**
* 抽樣查詢
* @param search
* @return
*/
public List<Document> getListSample(SearchVo search){
List<AggregationOperation> list = new ArrayList<>();
list.add(Aggregation.sample(search.getSampleSize()));
if(StrUtil.isNotEmpty(search.getColumns())){
list.add(Aggregation.project(search.getColumns().split(",")));
}
Aggregation aggregation = Aggregation.newAggregation(list);
return mongoTemplate.aggregate(aggregation, search.getCollName(), Document.class).getMappedResults();
}
/**
* 查詢樣本時間的上下限
* @param collName
* @return
*/
public Map<String, Object> getTimes(String collName){
long startTime = System.currentTimeMillis();
Map<String, Object> map = new HashMap<>();
Assert.notEmpty(collName, "collName");
List<AggregationOperation> list = new ArrayList<>();
list.add(Aggregation.project(MongoConstants.TIME_COLUMN));
list.add(Aggregation.group().min(MongoConstants.TIME_COLUMN).as("minTime").max(MongoConstants.TIME_COLUMN).as("maxTime"));
Aggregation aggregation = Aggregation.newAggregation(list);
Document doc = mongoTemplate.aggregate(aggregation, collName, Document.class).getRawResults();
if(doc != null){
if(Convert.toInt(doc.get("ok")) == 1){
List<Document> results = doc.get("results", List.class);
if(results != null && results.size() > 0){
Document obj = results.get(0);
if(obj != null){
map.put("minTime", obj.getLong("minTime"));
map.put("maxTime", obj.getLong("maxTime"));
}
}
}
}
if(CollUtil.isEmpty(map)){
map.put("minTime", null);
map.put("maxTime", null);
}
log.info("查詢樣本上下限時間,耗時:{}秒", (System.currentTimeMillis() - startTime)/1000);
return map;
}
/**
* 分頁查詢表資料
*
* @param search
* @return
*/
public TableDataInfo getPage(SearchInput search) {
List<JSONObject> list = new ArrayList<>();
Query query = getQuery(search);
long count = mongoTemplate.count(query, search.getCollName());
if (count > 0L) {
if (StrUtil.isEmpty(search.getSort())) {
// 預設根據時間排序
search.setSort(MongoConstants.TIME_COLUMN);
}
// 分頁:跳過前skip個文件,返回接下來的pageSize個文件
int skip = (search.getPageNum() - 1) * search.getPageSize();
query = query.with(Sort.by(search.getSort()).ascending()).skip(skip).limit(search.getPageSize());
list = mongoTemplate.find(query, JSONObject.class, search.getCollName());
}
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(list);
rspData.setMsg("查詢成功");
rspData.setTotal(count);
return rspData;
}
/**
* 根據條件查詢資料量
*
* @param search
* @return
*/
public long getCount(SearchInput search) {
Query query = getQuery(search);
return mongoTemplate.count(query, search.getCollName());
}
/**
* 分頁查詢集合的資料
*
* @param search
* @return
*/
public List<Document> getListDoc(SearchInput search) {
Query query = getQuery(search);
if (StrUtil.isNotEmpty(search.getSort())) {
query = query.with(Sort.by(search.getSort()).ascending());
}
int skip = (search.getPageNum() - 1) * search.getPageSize();
query = query.skip(skip).limit(search.getPageSize());
return mongoTemplate.find(query, Document.class , search.getCollName());
}
/**
* 隨機查詢一條資料
* @param collName
* @return
*/
public JSONObject getOne(String collName){
Query query = new Query();
query = query.limit(1);
return mongoTemplate.findOne(query, JSONObject.class, collName);
}
public Query getQuery(SearchInput search) {
Criteria criteria = new Criteria();
List<Criteria> criteriaList = new ArrayList<>();
if (StrUtil.isNotEmpty(search.getBeginTime())) {
criteriaList.add(Criteria.where(MongoConstants.TIME_COLUMN).gte(Convert.toLong(search.getBeginTime())));
}
if (StrUtil.isNotEmpty(search.getEndTime())) {
criteriaList.add(Criteria.where(MongoConstants.TIME_COLUMN).lte(Convert.toLong(search.getEndTime())));
}
if (criteriaList.size() > 0) {
criteria.andOperator(criteriaList);
}
Query query = new Query(criteria);
if (StrUtil.isNotEmpty(search.getColumns())) {
query.fields().include(search.getColumns().split(","));
}
if(StrUtil.isNotEmpty(search.getExclude())){
query.fields().exclude(search.getExclude().split(","));
}
return query;
}
/**
* 根據條件複製一個新的集合資料
* @param search
*/
// @Async("threadPoolTaskExecutor")
public void copyCollection(SearchCopy search) {
long startTime = System.currentTimeMillis();
log.info("開始把集合[{}]結果輸出到另一個集合[{}]...", search.getCollName(), search.getNewId());
clearCollection(search.getNewId());
List<AggregationOperation> list = new ArrayList<>();
if(StrUtil.isNotEmpty(search.getColumns())){
list.add(Aggregation.project(search.getColumns().split(",")));
}
if(StrUtil.isNotEmpty(search.getBeginTime())){
list.add(Aggregation.match(new Criteria(MongoConstants.TIME_COLUMN).gte(Convert.toLong(search.getBeginTime()))));
}
if(StrUtil.isNotEmpty(search.getEndTime())){
list.add(Aggregation.match(new Criteria(MongoConstants.TIME_COLUMN).lte(Convert.toLong(search.getEndTime()))));
}
list.add(Aggregation.out(search.getNewId()));
Aggregation aggregation = Aggregation.newAggregation(list);
mongoTemplate.aggregateStream(aggregation, search.getCollName(), Document.class);
log.info("結果輸出完成,耗時:{}秒", (System.currentTimeMillis() - startTime)/1000);
}
}
MongoTemplate增強版
使用手冊:https://loser.plus/
使用MyBatisPlus的方式,優雅的操作MongoDB。
這種方式是如同Mysql表結構一樣,已知集合名稱和欄位名稱,預先定義好欄位型別,自動與Mongodb進行關係對映。