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

时间:2017-01-04 15:26:24

标签: java mongodb spring-data spring-mongo spring-mongodb

我有一个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中构建这种数据的更有效/实用的方法吗?

提前致谢!

3 个答案:

答案 0 :(得分:0)

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

class Animal {
    constructor(text) {
        this.speech = text;
    }

    static get name() {
        return "Animal";
    }

    get name() {
        return this.constructor.name;
    }

    speak() {
        console.log( this.name + ":"+ this.speech)
    }
}

class Tiger extends Animal {
    static get name() {
        return "Tiger"
    }
}

var animal = new Animal("hey there");
animal.speak();
var tiger = new Tiger("hello");
tiger.speak();

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

Spring Data MongoDB 1.10 RC1 (Ingalls), 2.0 M2 (Kay)版本(截至撰写时)有added support for $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")
    )