非常的簡易透過 Spring boot 提供的註解我們可以輕鬆地宣告和使用
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "connectivity")
public class Connectivity {
private String name;
private Integer number;
private String status;
private Integer signalStrength;
@Field("IPlist")
private List<Map<String, Object>> ipList;
private Integer contentRevision;
private String deviceId;
private Long contentTimestamp;
}
Document
則是宣告 collection。Field
annotation 可以幫助與 mongoDB 中定義的 field 進行映射。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "gnss")
public class Gnss {
@Id
private String id;
private Integer contentRevision;
private String sensorName;
private Map<String, Object> coords; // Json format
private Double coordsAccuracy;
private String service;
private Double speed;
private Double heading;
private Long timestamp;
private String deviceId;
private Long contentTimestamp;
}
那接下來我們要怎樣對 MongoDB 進行一些操作呢 ? 在 Spring boot 中也提供 API 給我們使用如下,透過繼層 MongoRepository
我們就可以有基本的 CRUD 操作。
@Repository
public interface GnssRepository extends MongoRepository<Gnss, String> {
@Query("{'deviceId' : ?0 }")
List<GnssMappingVO> getByDeviceId(@Param("id") String id);
}
以下透過 MongoRepository 進行操作
@Override
public List<Gnss> getAllGnss() {
// basic query
return gnssRepository.findAll();
}
@Override
public Gnss getById(String id) {
// basic query
log.debug("Find Gnss by id:{}", id);
return gnssRepository.findById(id).orElse(null);
}
當然也可以使用 mongoTemplate 進行存取操作。
@Override
public List<GnssMappingVO> getListDeviceIdCustom(String id) {
// Use Query method
Query query = new Query();
query.fields().include("id").include("sensorName").include("coords").include("deviceId"); // like SQL SELECT
query.addCriteria(Criteria.where("deviceId").is(id)); // WHERE condition
query.with(Sort.by(Sort.Direction.ASC, "sensorName", "deviceId")); // like SQL ORDER BY
List<Gnss> gnssList = mongoTemplate.find(query, Gnss.class);
List<GnssMappingVO> res = new ArrayList<>();
/**
* 回傳資料而外處理
*/
for (int i=0; i<gnssList.size(); i++){
GnssMappingVO gnssMappingVO = new GnssMappingVO().builder()
.id(gnssList.get(i).getId())
.sensorName(gnssList.get(i).getSensorName())
.coords(gnssList.get(i).getCoords())
.deviceId(gnssList.get(i).getDeviceId())
.build();
res.add(gnssMappingVO);
}
return res;
}
下面同樣是用另一種方式進行存取使用 Aggregates
。
@Override
public List<Gnss> getListByTimestampRangeBson(GnssListRequestVO queryVO) {
String deviceId_column = "deviceId";
String timestamp_column = "timestamp";
String gps_column = "coords";
/**
* User Bson query
*/
Bson bson = Filters.and(Arrays.asList(
Filters.eq(deviceId_column, queryVO.getQuery().getDeviceId()),
Filters.gte(timestamp_column, queryVO.getQuery().getStart().getTime()),
Filters.lte(timestamp_column, queryVO.getQuery().getEnd().getTime()))); // Like Where condition
Bson match = Aggregates.match(bson);
Bson sort = Aggregates.sort(Sorts.ascending(timestamp_column)); // sort
Bson fields = Aggregates.project(Projections.include(deviceId_column, timestamp_column, gps_column)); // Like SELECT
AggregateIterable<Document> findIterable = mongoTemplate.getCollection(collection).aggregate(Arrays.asList(match, fields, sort));
Gson gson = new Gson(); // 轉 JSON
JsonWriterSettings settings = JsonWriterSettings.builder()
.dateTimeConverter(new JsonDateTimeCoverter())
.int64Converter((value, writer) -> writer.writeNumber(value.toString()))
.build();
List<Gnss> res = StreamSupport.stream(findIterable.spliterator(), false)
.map(i -> gson.fromJson(i.toJson(settings), Gnss.class))
.collect(Collectors.toList());
return res;
}
MongoDB 在 Spring boot 中提供了很多好用的 API,當然這些東西都是還要讀文件才有的,自幹才是王道