Spring 引导和 MongoDB 未知运算符:$last
Spring Boot and MongoDB unknown operator: $last
我正在尝试使用 $group:
执行最简单的聚合操作
{ "_id" : "$sensor", "lastTimestamp" : { "$last" : "$timestamp"}}
示例记录如下:
sensor: A
timestamp: 3:27:14
value: 3.29
sensor: A
timestamp: 4:27:14
value: 5.29
如果我在 MongoDB Compass 中执行查询,那么它 returns 有效结果:
_id: "A"
lastTimestamp: 4:27:14
如果我将其作为 Spring Data Reposirory 的自定义查询来执行,例如
public interface EventDataProvider extends MongoRepository<Event, String> {
@Query("{ \"_id\" : \"$sensor\", \"lastTimestamp\" : { \"$last\" : \"$timestamp\"}}")
List<Object> customQuery();
}
然后我得到异常:
com.mongodb.MongoQueryException: Query failed with error code 2 and error message 'unknown operator: $last' on server localhost:27017
at com.mongodb.operation.FindOperation.call(FindOperation.java:735) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.operation.FindOperation.call(FindOperation.java:725) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:463) ~[mongodb-driver-core-3.11.2.jar:na]
你能告诉我如何使自定义查询工作吗?
谢谢
要使用 Spring 存储库对象 运行 聚合组查询,您必须使用 @Aggregation 而不是 @Query
。
从 Spring 引导应用程序定义存储库和 运行:
@Repository
public interface SensorRepository extends MongoReppsitory<Sensor, String> {
@Aggregation("{ $group : { _id : $sensor, lastTimestamp: { $last : $timestamp } } }")
List<SensorAggregate> groupBySensors();
}
运行 sensor
集合上的聚合:
@Autowired
private SensorRepository repos;
// ...
public void run(String... strings) throws Exception {
List<SensorAggregate> list = repos.groupBySensors();
list.forEach(System.out::println);
}
POJO 类 Sensor
和 SensorAggregate
:
public class Sensor {
private String id;
private String sensor;
private String timestamp;
private double value;
public Sensor(String id, String sensor, String timestamp, double value) {
this.id = id;
this.sensor = sensor;
this.timestamp = timestamp;
this.value = value;
}
public String getId() {
return id;
}
public String getSensor() {
return sensor;
}
public String getTimestamp() {
return timestamp;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return sensor + ", " + timestamp;
}
}
public class SensorAggregate {
private @Id String sensor;
private String lastTimestamp;
public PersonAggregate(String sensor, String lastTimestamp) {
this.sensor = sensor;
this.lastTimestamp = lastTimestamp;
}
public String getSensor() {
return sensor;
}
public String getLastTimestamp() {
return lastTimestamp;
}
@Override
public String toString() {
return sensor + ", " + lastTimestamp;
}
}
我正在尝试使用 $group:
执行最简单的聚合操作{ "_id" : "$sensor", "lastTimestamp" : { "$last" : "$timestamp"}}
示例记录如下:
sensor: A
timestamp: 3:27:14
value: 3.29
sensor: A
timestamp: 4:27:14
value: 5.29
如果我在 MongoDB Compass 中执行查询,那么它 returns 有效结果:
_id: "A"
lastTimestamp: 4:27:14
如果我将其作为 Spring Data Reposirory 的自定义查询来执行,例如
public interface EventDataProvider extends MongoRepository<Event, String> {
@Query("{ \"_id\" : \"$sensor\", \"lastTimestamp\" : { \"$last\" : \"$timestamp\"}}")
List<Object> customQuery();
}
然后我得到异常:
com.mongodb.MongoQueryException: Query failed with error code 2 and error message 'unknown operator: $last' on server localhost:27017
at com.mongodb.operation.FindOperation.call(FindOperation.java:735) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.operation.FindOperation.call(FindOperation.java:725) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:463) ~[mongodb-driver-core-3.11.2.jar:na]
你能告诉我如何使自定义查询工作吗?
谢谢
要使用 Spring 存储库对象 运行 聚合组查询,您必须使用 @Aggregation 而不是 @Query
。
从 Spring 引导应用程序定义存储库和 运行:
@Repository
public interface SensorRepository extends MongoReppsitory<Sensor, String> {
@Aggregation("{ $group : { _id : $sensor, lastTimestamp: { $last : $timestamp } } }")
List<SensorAggregate> groupBySensors();
}
运行 sensor
集合上的聚合:
@Autowired
private SensorRepository repos;
// ...
public void run(String... strings) throws Exception {
List<SensorAggregate> list = repos.groupBySensors();
list.forEach(System.out::println);
}
POJO 类 Sensor
和 SensorAggregate
:
public class Sensor {
private String id;
private String sensor;
private String timestamp;
private double value;
public Sensor(String id, String sensor, String timestamp, double value) {
this.id = id;
this.sensor = sensor;
this.timestamp = timestamp;
this.value = value;
}
public String getId() {
return id;
}
public String getSensor() {
return sensor;
}
public String getTimestamp() {
return timestamp;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return sensor + ", " + timestamp;
}
}
public class SensorAggregate {
private @Id String sensor;
private String lastTimestamp;
public PersonAggregate(String sensor, String lastTimestamp) {
this.sensor = sensor;
this.lastTimestamp = lastTimestamp;
}
public String getSensor() {
return sensor;
}
public String getLastTimestamp() {
return lastTimestamp;
}
@Override
public String toString() {
return sensor + ", " + lastTimestamp;
}
}