【问题标题】:Random documents from MongoDB using spring-data使用 spring-data 来自 MongoDB 的随机文档
【发布时间】:2016-03-13 22:34:24
【问题描述】:

我可以使用这个mongodb native query

db.books.aggregate(
   [ { $sample: { size: 15 } } ]
)

但是如何在spring-data-mongodb 中做到这一点?

我在Spring Aggregation FrameworkAggregation class中没有发现类似的操作

【问题讨论】:

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


【解决方案1】:

更新:

从 Spring Data v2.0 开始,您可以这样做:

SampleOperation matchStage = Aggregation.sample(5);
Aggregation aggregation = Aggregation.newAggregation(sampleStage);
AggregationResults<OutType> output = mongoTemplate.aggregate(aggregation, "collectionName", OutType.class);

原答案:

像 spring-mongo 这样的抽象层总是会落后于服务器发布的功能。因此,您最好自己为流水线阶段构建 BSON 文档结构。

在自定义类中实现:

public class CustomAggregationOperation implements AggregationOperation {
    private DBObject operation;

    public CustomAggregationOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}

然后在你的代码中使用:

Aggregation aggregation = newAggregation(
    new CutomAggregationOperation(
        new BasicDBObject(
            "$sample",
            new BasicDBObject( "size", 15 )
        )
    )
);

由于它实现了AggregationOperation,因此它可以很好地与现有的管道操作辅助方法一起使用。即:

Aggregation aggregation = newAggregation(
    // custom pipeline stage
    new CutomAggregationOperation(
        new BasicDBObject(
            "$sample",
            new BasicDBObject( "size", 15 )
        )
    ),
    // Standard match pipeline stage
    match(
        Criteria.where("myDate")
            .gte(new Date(new Long("949384052490")))
            .lte(new Date(new Long("1448257684431")))
    )
);

再说一遍,归根结底,一切都只是一个 BSON 对象。这只是一个接口包装器的问题,以便 spring-mongo 中的类方法解释结果并正确获取您定义的 BS​​ON 对象。

【讨论】:

  • 非常感谢,这正是我要找的,在 spring 文档中没有找到
  • Aggregation.newAggregation
【解决方案2】:

Blakes Seven 正确回答了这个问题,但是,我想提供一个更好的 AggregationOperation 实现,它遵循标准 Spring 实施

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.Assert;

public class SampleOperation implements AggregationOperation  {

    private int size;

    public SampleOperation(int size) {
        Assert.isTrue(size > 0, " Size must be positive!");
        this.size = size;
    }

    public AggregationOperation setSize(int size) {
        Assert.isTrue(size > 0, " Size must be positive!");
        this.size = size;
        return this;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return new BasicDBObject("$sample", context.getMappedObject(Criteria.where("size").is(size).getCriteriaObject()));
    }

}

之后,您可以使用构造函数创建 SampleOperation 对象,或者稍后通过setSize() 方法更改其大小,然后照常将其应用于aggregate() 函数。

更新:在 SpringBoot 2.0.0+ 和 Spring Framework 5.0 中:Spring Mongo 删除 DBObject 并替换为 org.bson.Document 因此最后一个过去应更新为:

    @Override
public Document toDocument(AggregationOperationContext aggregationOperationContext) {
    return new Document("$sample", aggregationOperationContext.getMappedObject(Criteria.where("size").is(size).getCriteriaObject()));

}

并删除@Override toDBObject

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多