[英]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.