问题描述
如何将以下 MongoDB 查询转换为我的 Java Spring 应用程序使用的查询?我找不到将 pipeline
与提供的 lookup 方法.
How would I convert the following MongoDB query into a query to be used by my Java Spring application? I can't find a way to use pipeline
with the provided lookup method.
这是我尝试转换的查询.我还想指出,我没有使用 $unwind
,因为我希望 deliveryZipCodeTimings
作为返回对象中的分组集合.
Here is the query I am attempting to convert. I also want to note that I didn't use $unwind
as I wanted the deliveryZipCodeTimings
to stay as a grouped collection in the return object.
db.getCollection('fulfillmentChannel').aggregate([
{
$match: {
"dayOfWeek": "SOME_VARIABLE_STRING_1"
}
},
{
$lookup: {
from: "deliveryZipCodeTiming",
let: { location_id: "$fulfillmentLocationId" },
pipeline: [{
$match: {
$expr: {
$and: [
{$eq: ["$fulfillmentLocationId", "$$location_id"]},
{$eq: ["$zipCode", "SOME_VARIABLE_STRING_2"]}
]
}
}
},
{
$project: { _id: 0, zipCode: 1, cutoffTime: 1 }
}],
as: "deliveryZipCodeTimings"
}
},
{
$match: {
"deliveryZipCodeTimings": {$ne: []}
}
}
])
推荐答案
基于@dnickless 提供的信息,我能够解决这个问题.我将发布完整的解决方案,希望将来对其他人有所帮助.
Building upon the info given by @dnickless, I was able to solve this. I'll post the complete solution in the hopes it helps someone else in the future.
我正在使用 mongodb-driver:3.6.4
首先,我必须创建一个自定义聚合操作类,以便我可以传入一个自定义 JSON mongodb 查询以用于聚合操作.这将允许我在 $lookup
中使用 pipeline
,而我正在使用的驱动程序版本不支持.
First, I had to create a custom aggregation operation class so that I could pass in a custom JSON mongodb query to be used in the aggregation operation. This will allow me to use pipeline
within a $lookup
which is not supported with the driver version I am using.
public class CustomProjectAggregationOperation implements AggregationOperation {
private String jsonOperation;
public CustomProjectAggregationOperation(String jsonOperation) {
this.jsonOperation = jsonOperation;
}
@Override
public Document toDocument(AggregationOperationContext aggregationOperationContext) {
return aggregationOperationContext.getMappedObject(Document.parse(jsonOperation));
}
}
现在我们已经能够将自定义 JSON 查询传递到我们的 mongodb spring 实现中,剩下的就是将这些值插入到 TypedAggregation 查询.
Now that we have the ability to pass a custom JSON query into our mongodb spring implementation, all that is left is to plug those values into a TypedAggregation query.
public List<FulfillmentChannel> getFulfillmentChannels(
String SOME_VARIABLE_STRING_1,
String SOME_VARIABLE_STRING_2) {
AggregationOperation match = Aggregation.match(
Criteria.where("dayOfWeek").is(SOME_VARIABLE_STRING_1));
AggregationOperation match2 = Aggregation.match(
Criteria.where("deliveryZipCodeTimings").ne(Collections.EMPTY_LIST));
String query =
"{ $lookup: { " +
"from: 'deliveryZipCodeTiming'," +
"let: { location_id: '$fulfillmentLocationId' }," +
"pipeline: [{" +
"$match: {$expr: {$and: [" +
"{ $eq: ['$fulfillmentLocationId', '$$location_id']}," +
"{ $eq: ['$zipCode', '" + SOME_VARIABLE_STRING_2 + "']}]}}}," +
"{ $project: { _id: 0, zipCode: 1, cutoffTime: 1 } }]," +
"as: 'deliveryZipCodeTimings'}}";
TypedAggregation<FulfillmentChannel> aggregation = Aggregation.newAggregation(
FulfillmentChannel.class,
match,
new CustomProjectAggregationOperation(query),
match2
);
AggregationResults<FulfillmentChannel> results =
mongoTemplate.aggregate(aggregation, FulfillmentChannel.class);
return results.getMappedResults();
}
这篇关于使用管道聚合的 Spring Data MongoDB 查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!