查询文档及其与mongodb中的条件匹配的所有子文档(使用spring)

我有一个MongoDB存储来自不同传感器的数据。 它具有以下结构:

{ "_id" : 1, "sensorName" : "Heart Rate", "samplePeriod" : 1000, "data" : [ { "timestamp" : NumberLong("1483537204046"), "dataPoints" : [ 68 70 ] }, { "timestamp" : NumberLong("1483537206046"), "dataPoints" : [ 68 70 ] } ] } { "_id" : 2, "sensorName" : "Ambient Light", "samplePeriod" : 500, "data" : [ { "timestamp" : NumberLong("1483537204058"), "dataPoints" : [ 56, 54, 54, 54 ] }, { "timestamp" : NumberLong("1483537206058"), "dataPoints" : [ 56, 54, 54, 54 ] } ] } 

现在例如我需要“心率” – 包含其所有字段及其“数据”字段的文档 – 与条件“1483537204000和1483537214000之间的时间戳”匹配的子文档。

我已经在另一个问题的mongo shell中得到了关于如何做到这一点的答案。 看到这段代码:

 aggregate([{ $match: { "_id": 1 } }, { "$project": { "_id": 1, "sensorName": 1, "samplePeriod": 1, "data": { "$filter": { "input": "$data", "as": "result", "cond": { $and: [{ $gte: ["$$result.timestamp", 1483537204000] }, { $lte: ["$$result.timestamp", 1483537214000] }] } } } } }]) 

但是我如何在java spring-data中执行此操作? 在spring-data中似乎没有像$ filter那样的东西。 有解决方法吗?

无论如何,$ filter的效率如何? 你能想到在mongodb中构建这种数据的更有效/实用的方法吗?

提前致谢!

您需要使用spring mongo数据依赖项中提供的MongoTemplate。 当前版本中没有对$ filter的开箱即用支持。 利用AggressionExpression。 在项目中包括以下投影。 使用1.8.5 spring mongo数据版本。

 Aggregation aggregation = newAggregation( match(Criteria.where("_id").is(1)), project( "_id", "sensorName", "samplePeriod").and(new AggregationExpression() { @Override public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) { DBObject filter = new BasicDBObject("input", "$data").append("as", "result").append("cond", new BasicDBObject("$and", Arrays. asList(new BasicDBObject("$gte", Arrays. asList("$$result.timestamp", 1483537204000L)), new BasicDBObject("$lte", Arrays. asList("$$result.timestamp", 1483537214000L))))); return new BasicDBObject("$filter", filter); } }).as("data") ); List dbObjects = monoTemplate.aggregate(aggregation, "collectionname", BasicDBObject.class).getMappedResults(); 

我认为通过使用展开和额外匹配可以实现同样的目的。 Spring mongo驱动程序确实提供放松支持,看起来更干净。

 aggregate([{ $match: { "_id": 1 } }, { $unwind : "$data" },{ $match : {'data.timestamp' : {$gte : 1483537204000, $lte : 1483537214000}} }, { $group : { _id : $_id, data : {$push:$data} } }]) 

Spring Data MongoDB 1.10 RC1(Ingalls),2.0 M2(Kay)版本(截至编写时) 增加了对$filter支持 ,这可以通过以下方式实现:

 Aggregation.newAggregation(Entity.class, match(Criteria.where("_id").is(1)), project("sensorName", "samplePeriod") .and( filter("data") .as("item") .by( GTE.of(field("item.timestamp"), 1483537204000) .LTE.of(field("item.timestamp"), 1483537214000) ) ).as("data") )