在mongodb中查询一个文档及其所有匹配条件的子文档(使用spring)
我有一个 MongoDB 存储来自不同传感器的数据.它的结构如下:
I have a MongoDB storing data from different sensors. It has the following structure:
{
"_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 之间"的子文档.
Now for example i need the "Heart Rate" - document with all of its fields and those of its "data" - subdocuments matching the condition "timestamp between 1483537204000 and 1483537214000".
我已经在另一个问题中得到了关于如何在 mongo shell 中执行此操作的答案.请参阅此代码:
I already got the answer on how to do this in the mongo shell in another Question. See this code:
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 这样的东西.有解决办法吗?
But how do I do this in java spring-data? It seems there is nothing like $filter in spring-data. Is there a workaround?
$filter 的效率如何?您能想出一种更有效/更实用的方式在 mongodb 中构建此类数据吗?
How efficient is $filter anyway? Can you think of a more efficient/practical way of structuring this kind of data in mongodb?
提前致谢!
推荐答案
你需要使用spring mongo数据依赖中提供的MongoTemplate.当前发行版本中没有对 $filter 的开箱即用支持.使用 AggressionExpression.在项目中包括以下投影.使用 1.8.5 spring mongo 数据版本.
You'll need to make use of MongoTemplate provided in the spring mongo data dependency. There is no out of box support for $filter in the current release version. Make use of AggressionExpression. Include below projection in project. Use 1.8.5 spring mongo data version.
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.<Object> asList(new BasicDBObject("$gte", Arrays.<Object> asList("$$result.timestamp", 1483537204000L)),
new BasicDBObject("$lte", Arrays.<Object> asList("$$result.timestamp", 1483537214000L)))));
return new BasicDBObject("$filter", filter);
}
}).as("data")
);
List<BasicDBObject> dbObjects = monoTemplate.aggregate(aggregation, "collectionname", BasicDBObject.class).getMappedResults();
相关文章