Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在mongodb中查询符合条件的文档及其所有子文档(使用spring)_Java_Mongodb_Spring Data_Spring Mongo_Spring Mongodb - Fatal编程技术网

Java 在mongodb中查询符合条件的文档及其所有子文档(使用spring)

Java 在mongodb中查询符合条件的文档及其所有子文档(使用spring),java,mongodb,spring-data,spring-mongo,spring-mongodb,Java,Mongodb,Spring Data,Spring Mongo,Spring Mongodb,我有一个MongoDB存储来自不同传感器的数据。其结构如下: { "_id" : 1, "sensorName" : "Heart Rate", "samplePeriod" : 1000, "data" : [ { "timestamp" : NumberLong("1483537204046"), "dataPoints" : [ 68 70 ]

我有一个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]
                    }]
                }
            }
        }
    }
}])
但是我如何在JavaSpring数据中做到这一点呢?在spring数据中似乎没有什么比$filter更好的了。有解决办法吗

美元过滤器到底有多高效? 您能想出一种更有效/更实用的方法在mongodb中构建此类数据吗


提前谢谢

您需要使用spring mongo数据依赖项中提供的MongoTemplate。当前版本中没有对$filter的现成支持。利用攻击性的表情。在项目中包括以下投影。使用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.<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();
Aggregation=newAggregation(
匹配(标准,其中(“_id”)为(1)),
项目(“\u id”、“sensorName”、“samplePeriod”)和(新的AggregationExpression(){
@凌驾
公共数据库对象toDbObject(聚合操作上下文聚合操作上下文){
DBObject filter=newBasicDBObject(“输入”,“$data”).append(“作为”,“结果”).append(“条件”,
新的BasicDBObject(“$and”,Arrays.asList)(新的BasicDBObject(“$gte”,Arrays.asList(“$$result.timestamp”,1483537204000L)),
新的BasicDBObject(“$lte”,Arrays.asList(“$$result.timestamp”,1483537214000L())”);
返回新的BasicDBObject(“$filter”,filter);
}
}).as(“数据”)
);
List dbObjects=monoTemplate.aggregate(聚合,“collectionname”,BasicDBObject.class).getMappedResults();

您需要使用spring mongo数据依赖项中提供的MongoTemplate。当前版本中没有对$filter的现成支持。利用攻击性的表情。在项目中包括以下投影。使用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.<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();
Aggregation=newAggregation(
匹配(标准,其中(“_id”)为(1)),
项目(“\u id”、“sensorName”、“samplePeriod”)和(新的AggregationExpression(){
@凌驾
公共数据库对象toDbObject(聚合操作上下文聚合操作上下文){
DBObject filter=newBasicDBObject(“输入”,“$data”).append(“作为”,“结果”).append(“条件”,
新的BasicDBObject(“$and”,Arrays.asList)(新的BasicDBObject(“$gte”,Arrays.asList(“$$result.timestamp”,1483537204000L)),
新的BasicDBObject(“$lte”,Arrays.asList(“$$result.timestamp”,1483537214000L())”);
返回新的BasicDBObject(“$filter”,filter);
}
}).as(“数据”)
);
List dbObjects=monoTemplate.aggregate(聚合,“collectionname”,BasicDBObject.class).getMappedResults();

我认为通过使用放松和额外的比赛也可以达到同样的效果。SpringMongo驱动程序确实提供了对放松的支持,而且看起来更干净

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

我认为通过放松和额外的比赛也可以达到同样的效果。SpringMongo驱动程序确实提供了对放松的支持,而且看起来更干净

aggregate([{
 $match: {
    "_id": 1
   }
 }, {
  $unwind : "$data"
 },{
   $match : {'data.timestamp' : {$gte : 1483537204000, $lte : 1483537214000}}
 }, {
  $group : {
      _id : $_id,
      data : {$push:$data}
  }
 }])
发布(截至编写时)已完成,可按如下方式实现:

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")
    )
发布(截至编写时)已完成,可按如下方式实现:

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")
    )

如果您计划使用Spring,我强烈建议您使用Spring数据,它将为您提供处理此类查询的方法。我已经在使用Spring数据(在本文中对此进行了更改)。我只有在创建新聚合时才会遇到困难。我可以“匹配”、“项目”,但不能“过滤”。看看这篇文章,我想如果你打算用Spring做这件事,你需要的是什么,我强烈建议你使用Spring数据,它将为你提供处理这类查询的方法。我已经在使用Spring数据了(在文本中对此进行了更改)。我只有在创建新聚合时才会遇到困难。我可以“匹配”、“项目”,但不能“筛选”。看看这篇文章,我想这是你需要的,但在大文档上,放松速度很慢,因为它会为每个条目创建单独的文档,不是吗?我想避免这种情况。相比之下,“过滤器”的性能如何?是什么让你认为放松会很慢?在我看来,如果不比投射阶段的过滤速度快,也一样,在投射阶段,每个数据都通过条件传递和解析。放松也给了我们手去做更复杂的动作。另外,如果您正在为一个具有16MB限制的文档执行操作,您将无法看到其中任何一个文档的性能差异。这并不完全正确。过滤器是就地操作。这可能与你的具体情况无关。如果您有大型文档,性能将受到影响。这是为过滤器量身定制的外壳。“你为什么要在没有必要的时候放松呢?”SagarReddy说,“这是感知,不是吗?”?对你来说,不需要放松,对我来说,投影内部不需要复杂的过滤操作。仅仅因为它在原地并不意味着它更好。之所以称之为“聚合”,是因为数据看起来是干净聚合的,而不是每个内部数据都使用过滤条件进行变形。但你当然有权发表你的意见。只是澄清一下,这并不取决于你的看法。我会让OP来决定。但是在大文档上展开很慢,因为它会为每个条目创建单独的文档,不是吗?我想避免这种情况。相比之下,“过滤器”的性能如何?是什么让你认为放松会很慢?在我看来,如果不比投射阶段的过滤速度快,也一样,在投射阶段,每个数据都通过条件传递和解析。放松也给了我们手去做更复杂的动作。另外,如果您正在为一个文档执行以下操作: