我有一个学生文档列表,其结构如下:
{
"_id" : 0,
"name" : "aimee Zank",
"scores" : [
{
"type" : "exam",
"score" : 1.463179736705023
},
{
"type" : "quiz",
"score" : 11.78273309957772
},
{
"type" : "homework",
"score" : 6.676176060654615
},
{
"type" : "homework",
"score" : 35.8740349954354
}
]
}
如你所见,每个学生都有一个包含4个分数的列表。我需要删除每个学生文档的最低“家庭作业”分数。每个学生有2个条目表示"homewok“类型的分数(4个元素数组中的最后2个条目)。分数类型的模式和顺序是一致的,并且对所有学生都具有相同的模式,感谢您的帮助。
这就是我到目前为止一直在努力实现的:
DBCursor cursor = collection.find();
try {
while(cursor.hasNext()) {
BasicDBObject doc = (BasicDBObject) cursor.next();
BasicDBList scoreList = (BasicDBList) doc.get("scores");
BasicDBObject hw1 = (BasicDBObject) scoreList.get("2");
double hw1Score = hw1.getDouble("score");
BasicDBObject hw2 = (BasicDBObject) scoreList.get("3");
double hw2Score = hw2.getDouble("score");
if (hw1Score > hw2Score) {
BasicDBObject update = new BasicDBObject("scores.score", hw2Score);
collection.update(doc, new BasicDBObject("$pull",update));
} else {
BasicDBObject update = new BasicDBObject("scores.score", hw1Score);
collection.update(doc, new BasicDBObject("$pull",update));
}
System.out.println(doc);
}
} finally {
cursor.close();
}
}
发布于 2018-08-24 04:35:22
这里的所有答案都很棒。我只想补充一点,如果有人想要使用Java操作符(从driver v3.1开始),那么他可以这样做,而不是使用"$pull“操作符:
...
Bson studentFilter = Filters.eq( "_id", doc.get("_id") );
Bson delete = Updates.pull("scores", new Document("score", lowestHomework).append("type", "homework"));
collection.updateOne(studentFilter, delete);
我觉得它更优雅。所以我的完整答案是:
public static void main(String[] args) {
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("school");
MongoCollection<Document> collection = database.getCollection("students");
List<Document> homeworks = collection.find()
.into(new ArrayList<Document>());
for(Document doc : homeworks)
{
ArrayList<Document> scores = (ArrayList<Document>) doc.get("scores");
//iterate over the scores of each student (there are 4 scores: quiz, exam and 2*homework)
double lowestHomework = Double.MAX_VALUE;
for(Document embeddedDoc : scores)
{
if(embeddedDoc.getString("type").equals("homework"))
{
Double score = embeddedDoc.getDouble("score");
if(score < lowestHomework)
{
lowestHomework = score;
}
}
}
Bson studentFilter = Filters.eq( "_id", doc.get("_id") );
Bson delete = Updates.pull("scores", new Document("score", lowestHomework).append("type", "homework"));
collection.updateOne(studentFilter, delete);
}
client.close();
}
发布于 2015-01-22 12:18:27
我知道这不是最好的解决方案(更好的方法是对每个文档的作业分数进行排序,然后将数组大小限制为3)。但这也是可行的:)
try {
while(cursor.hasNext()) {
BasicDBObject doc = (BasicDBObject) cursor.next();
BasicDBList scoreList = (BasicDBList) doc.get("scores");
doc.remove("scores");
BasicDBObject hw1 = (BasicDBObject) scoreList.get("2");
double hw1Score = hw1.getDouble("score");
BasicDBObject hw2 = (BasicDBObject) scoreList.get("3");
double hw2Score = hw2.getDouble("score");
if (hw1Score > hw2Score) {
scoreList.remove(3);
} else {
scoreList.remove(2);
}
doc.put("scores",scoreList);
collection.save(doc);
System.out.println(doc);
}
} finally {
cursor.close();
}
}
}
发布于 2016-08-19 23:49:59
试试这个;我假设最高分是100分:
for (Document document : cursor) {
ArrayList<Document> list = (ArrayList<Document>) document.get("scores");
double score = 100;
for (Document doc : list) {
if(doc.getString("type").equals("homework")){
if(doc.getDouble("score") < score){
score = doc.getDouble("score");
}
}
}
BasicDBObject update = new BasicDBObject("scores", new BasicDBObject("score", score).append("type", "homework"));
collection.updateOne(document, new BasicDBObject("$pull", update));
}
https://stackoverflow.com/questions/28071078
复制相似问题