我是mongodb和聚合框架的新手。
我们有一个类UserMetaData和一个UserMetaData列表。我需要根据传递给方法solve((的userMetaDataList来获取数据。目前,我正在迭代列表,并从monodb中一个接一个地获取相应的集合。由于数据库调用是针对列表中的每个元素进行的,因此这将成为一项非常昂贵的操作。有没有任何方法可以一次从mongodb中获取所有所需的数据(更像是批量获取操作(。
mongodb-执行批处理查询本文提供的解决方案不能满足当前场景的要求。请帮忙!!
这就是我目前的工作方式。
class UserMetaData{
String userId;
String vehicleId;
String vehicleColour;
String orderId;
}
public List<String> getOrderIds(List<UserMetaData> userMetaDataList) {
List<String> orderIds = new ArrayList<>();
for (UserMetaData userMetadata : userMetaDataList) {
try {
BasicDBObject matchDBObject = new BasicDBObject("user_id", new BasicDBObject("$eq", userMetadata.getUserId()));
matchDBObject.append("vehicle_id", new BasicDBObject("$eq", userMetadata.getVehicleID()));
matchDBObject.append("vehicle_colour", new BasicDBObject("$in", ImmutableSet.of("WHITE", "BLACK")));
Document document = eventCollection.find(matchDBObject)
.projection(new BasicDBObject("order_id", "1"))
.first();
orderIds.add(document.get("order_id").toString());
} catch (Exception e) {
log.info("Exception occurred while fetching order id for user_id: {} asset_id:{} - {}", metadata.getUserId(), metadata.getAssetID(), e);
}
}
return ordersIds;
}
我想在一个查询中获取所有相应的数据。请求帮助。
您可以使用$OR条件连接所有过滤器,并一次获取完整列表。。。
我想在一个查询中获取所有相应的数据。
您可以使用这种方法并将查询作为单个操作执行(避免for循环(。
考虑集合test
:中的示例文档
{ "_id" : ObjectId("621762e2cda7c6394d557f37"), "userid" : 1, "name" : "ijk", "orderid" : "11" }
{ "_id" : ObjectId("621762efcda7c6394d557f38"), "userid" : 12, "name" : "abc", "orderid" : "99" }
{ "_id" : ObjectId("621762fccda7c6394d557f39"), "userid" : 13, "name" : "xyz", "orderid" : "100" }
要筛选的对象数组:
var DOCS = [
{ userid: 12, name: "abc" },
{ userid: 13, name: "xyz" }
]
通过DOCS
:过滤的查询
db.test.find(
{
$expr: {
$in: [ { userid: "$userid", name: "$name" }, DOCS ]
}
},
{
orderid: 1
}
)
输出具有userid
、12
和13
的文档。
[EDIT-ADD]
这种聚合是对find
:的改进
db.test.aggregate([
// This matches the 'userid' and 'name' fields with the input list 'DOCS'
{
$match: {
$expr: {
$in: [ { userid: "$userid", name: "$name" }, DOCS ]
}
}
},
// The grouping will select only the first matching for the 'userid' and 'name'
// (this is as per the question post's code: `.first()`)
{
$group: {
_id: {
userid: "$userid",
name: "$name"
},
orderid: {
$first: "$orderid"
}
}
},
// Remove the '_id' field
// Now the result has just the 'orderid' field only
{
$unset: "_id"
}
])