Mongodb Java:根据元素的特定条件删除文档中嵌入数组的元素
我有一份学生文件列表,其结构如下:Mongodb Java:根据元素的特定条件删除文档中嵌入数组的元素,java,arrays,mongodb,Java,Arrays,Mongodb,我有一份学生文件列表,其结构如下: { "_id" : 0, "name" : "aimee Zank", "scores" : [ { "type" : "exam", "score" : 1.463179736705023 }, { "type" : "quiz",
{
"_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();
}
}
迭代数组并找到最小分数。伪代码:
min <- infinity
minIndex = -1
for index <- 0; index < elements.getScores().size(); index <- index + 1 do
if min > elements.getScores().get(index) then
min <- elements.getScores().get(index)
minIndex <- index
end if
end for
min我知道这不是最好的解决方案(更好的方法是对每个文档的家庭作业分数进行排序,然后将数组大小限制为3)。但这也有效:)
}我尝试使用本机mongodb命令,该命令执行起来非常简单。我试着对给定的问题陈述进行测试。使用以下两个命令使其工作
1) cursor=db.students.aggregate([{“$unwind”:“$scores”},{“$match”:{“scores.type”:“家庭作业”},{“$group”:{“id”:“$\id”,“minitem”:“{$min”:“$scores.scores”}]),null
2) cursor.forEach(函数(coll){db.students.update({'u-id':coll.id},{'pull':{'scores':{'scores':{'scores':coll.minitem}}})试试这个;我假设最高分数为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));
}
for(文档:游标){
ArrayList=(ArrayList)document.get(“分数”);
双倍得分=100分;
用于(文档:列表){
if(doc.getString(“type”).equals(“家庭作业”)){
如果(doc.getDouble(“分数”)
我尝试使用MongoDB java驱动程序的聚合器类来解决这个问题。请参考以下工作代码
AggregateIterable<Document> aiter = collection.aggregate(
Arrays.asList(Aggregates.unwind("$scores"),Aggregates.match(Filters.eq("scores.type", "homework")),
Aggregates.sort(Sorts.orderBy(Sorts.ascending("_id"), Sorts.ascending("scores.score")))));
collection = database.getCollection("students");
MongoCursor<Document> cursor = aiter.iterator();
int pid = -1;
while (cursor.hasNext()) {
Document doc = cursor.next();
int cid = doc.getInteger("_id");
double scoresScore = doc.get("scores", Document.class).getDouble("score");
if (pid != cid) {
// delete
BasicDBObject update = new BasicDBObject("scores",
new BasicDBObject("score", scoresScore).append("type", "homework"));
collection.updateOne(Filters.eq("_id", cid), new BasicDBObject("$pull", update));
}
pid = cid;
}
AggregateIterable aiter=collection.aggregate(
Arrays.asList(Aggregates.unwind($scores))、Aggregates.match(Filters.eq(“scores.type”、“家庭作业”),
Aggregates.sort(Sorts.orderBy(Sorts.升序(_-id))、Sorts.升序(“scores.score”));
collection=database.getCollection(“学生”);
MongoCursor=aiter.iterator();
int-pid=-1;
while(cursor.hasNext()){
Document doc=cursor.next();
int cid=doc.getInteger(“_id”);
double scorescore=doc.get(“分数”,Document.class).getDouble(“分数”);
如果(pid!=cid){
//删除
BasicDBObject更新=新的BasicDBObject(“分数”,
新的BasicDBObject(“分数”,scorescore)。追加(“类型”,“作业”);
collection.updateOne(Filters.eq(“_id”,cid),新的BasicDBObject(“$pull”,update));
}
pid=cid;
}
这是我的方法,也许有人会发现它更干净、更容易理解:
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("school");
final MongoCollection<BasicDBObject> collection = database.getCollection("students",BasicDBObject.class);
MongoCursor<BasicDBObject> cursor = collection.find().iterator();
while(cursor.hasNext())
{
double min_score = 999;
BasicDBObject doc = cursor.next();
BasicDBList scores = (BasicDBList) doc.get("scores");
for (Object score : scores)
{
BasicDBObject x = (BasicDBObject) score;
if (x.get("type").equals("homework"))
{
if (x.getDouble("score") < min_score)
{
min_score = x.getDouble("score");
}
}
}
if (min_score == 999){
continue;
}
BasicDBObject query = new BasicDBObject("_id", doc.get("_id")); // Find this Document
BasicDBObject fields = new BasicDBObject("scores",
new BasicDBObject( "score", min_score)); // With those fields
BasicDBObject update = new BasicDBObject("$pull",fields); // And remove any the matched results.
collection.updateOne(query, update);
}
MongoClient客户端=新的MongoClient();
MongoDatabase database=client.getDatabase(“学校”);
最终MongoCollection集合=database.getCollection(“学生”,BasicDBObject.class);
MongoCursor=collection.find().iterator();
while(cursor.hasNext())
{
双倍min_分数=999;
BasicDBObject doc=cursor.next();
基本列表分数=(基本列表)文档获取(“分数”);
对于(对象分数:分数)
{
BasicDBObject x=(BasicDBObject)得分;
如果(x.get(“type”).equals(“家庭作业”))
{
如果(x.getDouble(“分数”)
$pull
操作符从现有数组中删除与指定条件匹配的一个或多个值的所有实例。package com.mongodb;
package com.mongodb;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
public class HWDeleteArray {
public static void main(String[] args) {
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("school");
MongoCollection<Document> collection = database.getCollection("students");
List<Document> all = collection.find().into(new ArrayList<Document>());
int i = 0;
Double s1 =0.0;
Double s2 =0.0;
Document doc1 = null;
Document doc2 = null;
for(Document cur:all) {
List<Document> scores = (List<Document>) cur.get("scores");
for(Document score:scores) {
if(score.getString("type").equals("homework")) {
if(i==0) {
i++;
s1 = (Double) score.get("score");
doc1 = score;
}else {
i--;
s2 = (Double) score.get("score");
doc2 = score;
if(s1 < s2) {
doc1.clear();
collection.replaceOne(new Document("_id",cur.get("_id")),cur);
}else {
doc2.clear();
collection.replaceOne(new Document("_id",cur.get("_id")),cur);
}
}
}
}
}
}
}
导入java.util.ArrayList;
导入java.util.List;
导入org.bson.Document;
导入com.mongodb.client.MongoCollection;
导入com.mongodb.client.MongoDatabase;
公共类HWDeleteArray{
公共静态void main(字符串[]args){
MongoClient=新的MongoClient();
MongoDatabase database=client.getDatabase(“学校”);
MongoCollection collection=database.getCollection(“学生”);
List all=collection.find().into(new ArrayList());
int i=0;
双s1=0.0;
双s2=0.0;
文档doc1=null;
文档doc2=null;
用于(当前文件:全部){
列表分数=(列表)当前获取(“分数”);
对于(文件分数:分数){
if(score.getString(“type”).equals(“家庭作业”)){
如果(i==0){
i++;
s1=(双倍)得分。获取(“得分”);
doc1=分数;
}否则{
我--;
s2=(双倍)得分。获取(“得分”);
doc2=得分;
if(s1
尝试以下代码:
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Filters.eq;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Projections;
MongoClient client = new MongoClient();
String str, str2;
Double sub;
MongoDatabase db = client.getDatabase("school");
MongoCollection<Document> coll = db.getCollection("students");
//coll.drop();
MongoCursor<Document> cursor = coll.find().iterator();
List<Document> student = coll.find().into(new ArrayList<Document>());
for(Document doc :student){
List<Document> scores = (List<Document>)doc.get("scores");
doc.remove("scores");
List<Document> scores2 = scores.subList(2,3);
System.out.println(scores2.toString());
str = (scores2.toString()).substring(32, (scores2.toString()).length()-3);
System.out.println(str);
List<Document> scores3 = scores.subList(3,4);
System.out.println(scores3.toString());
str2 = (scores3.toString()).substring(32, (scores3.toString()).length()-3);
System.out.println(str2);
sub = Double.parseDouble(str2) - Double.parseDouble(str);
if(sub >0){
scores.remove(2);
doc.put("scores", scores);
}else if(sub == 0){
scores.remove(2);
doc.put("scores", scores);
}else{
scores.remove(3);
doc.put("scores", scores);
}
Document cur = cursor.next();
System.out.println(cur);
System.out.println(doc);
coll.findOneAndReplace(cur, doc);
}
import java.ut
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Filters.eq;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Projections;
MongoClient client = new MongoClient();
String str, str2;
Double sub;
MongoDatabase db = client.getDatabase("school");
MongoCollection<Document> coll = db.getCollection("students");
//coll.drop();
MongoCursor<Document> cursor = coll.find().iterator();
List<Document> student = coll.find().into(new ArrayList<Document>());
for(Document doc :student){
List<Document> scores = (List<Document>)doc.get("scores");
doc.remove("scores");
List<Document> scores2 = scores.subList(2,3);
System.out.println(scores2.toString());
str = (scores2.toString()).substring(32, (scores2.toString()).length()-3);
System.out.println(str);
List<Document> scores3 = scores.subList(3,4);
System.out.println(scores3.toString());
str2 = (scores3.toString()).substring(32, (scores3.toString()).length()-3);
System.out.println(str2);
sub = Double.parseDouble(str2) - Double.parseDouble(str);
if(sub >0){
scores.remove(2);
doc.put("scores", scores);
}else if(sub == 0){
scores.remove(2);
doc.put("scores", scores);
}else{
scores.remove(3);
doc.put("scores", scores);
}
Document cur = cursor.next();
System.out.println(cur);
System.out.println(doc);
coll.findOneAndReplace(cur, doc);
}
List<Document> all = (List<Document>) collection.find().into(new ArrayList<Document>());
for (Document current : all){
Object id = current.get("_id");
List<Document> i = (List<Document>) current.get("scores");
if(i.get(2).getDouble("score")>i.get(3).getDouble("score")){
collection.updateOne(new Document("_id", id),new Document("$pull",new Document("scores",new Document("score",i.get(3).getDouble("score")))));
} else{
collection.updateOne(new Document("_id", id),new Document("$pull",new Document("scores",new Document("score",i.get(2).getDouble("score")))));
}
}
}
List<Document> documents = collection.find().into(new ArrayList<Document>());
for (Document document : documents) {
List<Document> scores = (List<Document>) document.get("scores");
Document minDoc = null;
for (Document score : scores) {
if ("homework".equals(score.getString("type")) && (minDoc == null || minDoc.getDouble("score") > score.getDouble("score"))) {
minDoc = score;
}
}
collection.updateOne(new Document("_id", document.get("_id")), new Document("$pull", new Document("scores", minDoc)));
}
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import java.util.ArrayList;
import java.util.List;
import static com.mongodb.client.model.Updates.pull;
public class RemoveLowestScoreArray {
public static void main(String[] args) {
MongoDatabase database;
try (MongoClient client = new MongoClient()) {
database = client.getDatabase("school");
MongoCollection<Document> collection = database.getCollection("students");
List<Document> students = collection.find().into(new ArrayList<>());
for (Document student : students) {
Document lowestScore = null;
for (Document score : (List<Document>) student.get("scores")) {
if (score.getString("type").equals("homework")) {
if (lowestScore == null || score.getDouble("score") < (lowestScore.getDouble("score"))) {
lowestScore = score;
}
}
}
collection.updateOne(student, pull("scores", lowestScore));
}
}
}
}
List<Document> results =
collection.aggregate(asList(
new Document("$unwind","$scores"),
new Document("$match", new Document("scores.type", new Document("$eq", "homework"))),
new Document("$group", new Document("_id", "$_id")
.append("score", new Document("$min", "$scores.score")))))
.into(new ArrayList<Document>());
for(Document doc : results)
{
Integer id = doc.getInteger("_id");
Double score = doc.getDouble("score");
UpdateResult result = collection.updateOne(new Document("_id",new Document("$eq",id)),
new Document("$pull", new Document("scores",
new Document("score", 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);
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();
}