简体   繁体   English

来自MongoDB的随机文档使用spring-data

[英]Random documents from MongoDB using spring-data

I'm able to do it by using this mongodb native query : 我可以通过使用这个mongodb本机查询来做到这一点:

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

But how to do it in spring-data-mongodb ? 但是如何在spring-data-mongodb做到这一点?

I found no similar operation in Aggregation class of Spring Aggregation Framework 我在Spring Aggregation Framework的 Aggregation类中找不到类似的操作

Update: 更新:

Starting with v2.0 of Spring Data you can do this: 从Spring Data v2.0开始,您可以这样做:

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

Original answer: 原始答案:

Abstraction layers like spring-mongo are always going to lag way behind server released features. 像spring-mongo这样的抽象层总是落后于服务器发布的功能。 So you are best off contructing the BSON document structure for the pipeline stage yourself. 因此,您最好自己为流水线阶段构建BSON文档结构。

Implement in a custom class: 在自定义类中实现:

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);
    }
}

And then use in your code: 然后在你的代码中使用:

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

Since this implements AggregationOperation this works well with the exising pipeline operation helper methods. 由于这实现了AggregationOperation因此适用于现有的管道操作辅助方法。 ie: 即:

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

So again, everything is just a BSON Object at the end of the day. 所以,在一天结束时,一切都只是一个BSON对象。 It's just a matter of having an interface wrapper so that the class methods in spring-mongo interpret the result and get your defined BSON Object correctly. 这只是一个接口包装器的问题,以便spring-mongo中的类方法解释结果并正确获取您定义的BSON对象。

Blakes Seven answered it correctly, however, I want to offer a nicer implementation of AggregationOperation, which follows standard Spring implementation 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()));
    }

}

After that, you can create SampleOperation object with constructor, or later change the size of it by setSize() method, and apply it to aggregate() function as normal. 之后,您可以使用构造函数创建SampleOperation对象,或者稍后通过setSize()方法更改它的大小,并将其应用于aggregate()函数。

Update: In SpringBoot 2.0.0+ and Spring Framework 5.0: Spring Mongo drop DBObject and replace by org.bson.Document therefore the last past should be updated as: 更新:在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()));

} }

And remove the @Override toDBObject 并删除@Override toDBObject

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM