我有一系列文件:
{"name":1,"b":3,"c":3}
{"name":1,"b":3,"c":5}
{"name":1,"b":3,"c":6}
{"name":2,"b":6,"c":6}
{"name":2,"b":6,"c":7}
{"name":2,"b":6,"c":3}
{"name":3,"b":2,"c":3}
{"name":4,"b":2,"c":3}
我想将该集合合并到以下结果中:
{"name":1,"b":3,"c":[3,5,6]}
{"name":2,"b":6,"c":[6,7,3]}
{"name":3,"b":2,"c":3}
{"name":4,"b":2,"c":3}
这意味着消除重复文档并将其c
字段保存为数组。 c
将是一个数组。
注意:第一个(例如"名称")和第二个(例如" b")字段对于每个文档都是唯一的。
while (cursor.hasNext()) {
DBObject currentObject = cursor.next();
String currentName = (String)currentObject.get("name");
if (currentName.equals(previousName) && !previousName.equals(""))
{
// what should i write here
collection.remove(previousObject);
}
previousObject = currentObject;
previousName = (String)previousObject.get("name");
}
答案 0 :(得分:1)
您可以在进度时将名称地图和DBObjects
以及push
保存到值中,如下所示:
Map<String,DBObject> names = new HashMap<String, DBObject>();
while (cursor.hasNext()) {
DBObject currentObject = cursor.next();
String currentName = (String) currentObject.get("name");
DBObject o = names.get(currentName);
if (o!=null) { //means you already have it.
Integer c = (Integer) currentObject.get("c");
collection.remove(currentObject);
collection.update(o,new BasicDBObject("$push",new BasicDBObject("c",c)));
}else {
names.put(currentName,currentObject);
}
}
答案 1 :(得分:0)
我不了解MongoDB,但是因为naimdjon说你需要一些地图。 以下是针对您的问题的通用Java解决方案:
模拟输入的课程
import java.util.HashSet;
import java.util.Set;
public class SomeDbObject {
Integer name;
Integer b;
Set<Integer> c;
public SomeDbObject(Integer name, Integer b, Integer c){
this.name = name;
this.b = b;
this.c = new HashSet<>();
this.c.add(c);
}
public String toString(){
return c.toString();
}
}
现在是一个包含数据集的测试类(使用名称和b作为&#34;键&#34;):
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
public class SomeDbObjectTest {
@Test
public void testProblem(){
List<SomeDbObject> l = new ArrayList<SomeDbObject>();
l.add(new SomeDbObject(1,3,3));
l.add(new SomeDbObject(1,3,5));
l.add(new SomeDbObject(1,3,6));
l.add(new SomeDbObject(2,6,6));
l.add(new SomeDbObject(2,6,7));
l.add(new SomeDbObject(2,6,3));
l.add(new SomeDbObject(3,2,3));
l.add(new SomeDbObject(4,2,3));
Map<Integer,Map<Integer,SomeDbObject>> m = new HashMap<Integer,Map<Integer,SomeDbObject>>();
for(SomeDbObject tc : l){
Map<Integer,SomeDbObject> mTc = m.get(tc.name);
if(mTc == null){
mTc = new HashMap<Integer,SomeDbObject>();
mTc.put(tc.b, tc);
m.put(tc.name, mTc);
} else {
SomeDbObject alreadyExistingRec = mTc.get(tc.b);
alreadyExistingRec.c.addAll(tc.c);
}
}
System.out.println(m);
}
}
答案 2 :(得分:0)
您可以使用聚合框架在shell中使用以下查询来执行此操作:
db.foo.aggregate([
{$group:{_id:{name:"$name", b:"$b"}, c:{$addToSet:"$c"}}},
{$project:{_id:0, name:"$_id.name", b:"$_id.b", c:1}}
])
此查询可以翻译为Java。