我是MongoDB
的新手,我正在尝试创建一个查询,我觉得这很简单(好吧,改为SQL
它会)但我无法得到它完成。
因此,在此集合中有一个集合patients
,使用patient
属性标识单个id
。 (不是mongodbs _id
!!)单个patient
可以有多个版本,其版本由meta.versionId
字段决定。
为了查询所有“当前版本的患者”,我需要获得具有patient
特定id
versionId
的每个 AggregateIterable<Document> allPatients = db.getCollection("patients").aggregate(Arrays.asList(
new Document("$group", new Document("_id", "$id")
.append("max", new Document("$max", "$meta.versionId")))));
allPatients.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
System.out.println(document.toJson());
}
});
。
到目前为止,我已经得到了这个:
{ "_id" : "2.25.260185450267055504591276882440338245053", "max" : "5" }
{ "_id" : "2.25.260185450267055504591276882441338245099", "max" : "0" }
导致以下输出(使用我非常有限的测试数据):
patients
到目前为止似乎工作,但我需要获得整个id : 2.25.260185450267055504591276882440338245053
集合。
现在我只知道patient
最大版本是“5”,依此类推。当然,我现在可以为每个条目创建一个自己的查询,并从mongodb顺序获取特定id
/ versionId
- 组合的每个{{1}}文档,但这似乎是一个可怕的解决方案!有没有其他方法可以完成它?
答案 0 :(得分:1)
如果您知道要检索的列,请说出患者姓名,地址等,我猜您可以将这些列附加到值为1的文档中。
AggregateIterable<Document> allPatients = db.getCollection("patients").aggregate(Arrays.asList(
new Document("$group", new Document("_id", "$id")
.append("max", new Document("$max", "$meta.versionId")).append("name",1).append("address",1))));
答案 1 :(得分:1)
可能适用于您的方法是首先使用 $sort
管道运算符命令meta.versionId
字段进入管道中的文档。但请注意, $sort
阶段的内存限制为100兆字节。默认情况下,如果超出此限制, $sort
将产生错误。
要允许处理大型数据集,请将allowDiskUse
选项设置为true,以启用 $sort
操作以写入临时文件。有关详细信息,请参阅 aggregate()
方法中的allowDiskUse
选项。
排序后,您可以对订购的文档进行分组,使用 $first
或 $last
运算符进行汇总(具体取决于获得其他字段。
考虑运行以下mongo shell管道操作作为一种方式 展示这个概念:
Mongo shell
pipeline = [
{ "$sort": {"meta.versionId": -1}}, // order the documents by the versionId field descending
{
"$group": {
"_id": "$id",
"max": { "$first": "$meta.versionId" }, // get the maximum versionId
"active": { "$first": "$active" }, // Whether this patient's record is in active use
"name": { "$first": "$name" }, // A name associated with the patient
"telecom": { "$first": "$telecom" }, // A contact detail for the individual
"gender": { "$first": "$gender" }, // male | female | other | unknown
"birthDate": { "$first": "$birthDate" } // The date of birth for the individual
/*
And many other fields
*/
}
}
]
db.patients.aggregate(pipeline);
Java测试实施
public class JavaAggregation {
public static void main(String args[]) throws UnknownHostException {
MongoClient mongo = new MongoClient();
DB db = mongo.getDB("test");
DBCollection coll = db.getCollection("patients");
// create the pipeline operations, first with the $sort
DBObject sort = new BasicDBObject("$sort",
new BasicDBObject("meta.versionId", -1)
);
// build the $group operations
DBObject groupFields = new BasicDBObject( "_id", "$id");
groupFields.put("max", new BasicDBObject( "$first", "$meta.versionId"));
groupFields.put("active", new BasicDBObject( "$first", "$active"));
groupFields.put("name", new BasicDBObject( "$first", "$name"));
groupFields.put("telecom", new BasicDBObject( "$first", "$telecom"));
groupFields.put("gender", new BasicDBObject( "$first", "$gender"));
groupFields.put("birthDate", new BasicDBObject( "$first", "$birthDate"));
// append any other necessary fields
DBObject group = new BasicDBObject("$group", groupFields);
List<DBObject> pipeline = Arrays.asList(sort, group);
AggregationOutput output = coll.aggregate(pipeline);
for (DBObject result : output.results()) {
System.out.println(result);
}
}
}