2016-02-17 2 views
3

У меня есть коллекция в моем MongoDB с тысячами документов. Каждый документ выглядит следующим образом в настоящее время:Добавить новое поле в объект в документе MongoDB

{ 
    "_id" : ObjectId("1"), 
    "FIELD1" : { 
     "STR1" : "some text", 
     "STR2" : "some text", 
     "STR3" : "some text", 
     "STR4" : "some text" 
    }, 
    "FIELD2" : "some text" 
} 

С в следующем фрагменте кода, мне удалось добавить новое поле для ВСЕХ документов 4000 +:

// Add new field to all documents 
BasicDBObject query = new BasicDBObject(); 
BasicDBObject update = new BasicDBObject(); 
update.put("$set", new BasicDBObject(NEW_DB_FIELD_NAME, new BasicDBObject())); 
WriteResult result = coll.update(query, update, true, true); 

Документы имеет новую структуру, в которой FIELD3 является Object:

{ 
    "_id" : ObjectId("1"), 
    "FIELD1" : { 
     "STR1" : "some text", 
     "STR2" : "some text", 
     "STR3" : "some text", 
     "STR4" : "some text" 
    }, 
    "FIELD2" : "some text", 
    "FIELD3" : { 
    } 
} 

Теперь проблема в том, что я хотел бы добавить несколько элементов FIELD3 где каждый элемент является Object содержащий 2 String S:

{ 
    "_id" : ObjectId("1"), 
    "FIELD1" : { 
     "STR1" : "some text", 
     "STR2" : "some text", 
     "STR3" : "some text", 
     "STR4" : "some text" 
    }, 
    "FIELD2" : "some text", 
    "FIELD3" : { 
     "ITEM1" : { 
      "STR1" : "", 
      "STR2" : "" 
     }, 
     "ITEM2" : { 
      "STR1" : "", 
      "STR2" : "" 
     }, 
     "ITEM3" : { 
      "STR1" : "", 
      "STR2" : "" 
     } 
    } 
} 

То, что я попытался это:

BasicDBObject query = new BasicDBObject{"FIELD2","some text"}; 
BasicDBObject update = new BasicDBObject(); 
update.put("$set", new BasicDBObject("FIELD3.ITEM1.STR1", "some text").append("FIELD3.ITEM1.STR2", "some text"); 
result = coll.update(query, update, true, false); 

Проблема заключается в том, что я могу получить только один новый пункт под FIELD3. Он продолжает заменяться новыми значениями, когда я просматриваю элементы.

Пожалуйста, помогите!

UPDATE:

С помощью @Explosion таблетки, мне удалось добавить все ITEM1, ITEM2, ITEM3 и т.д., чтобы мой вновь созданный FIELD3. Тем не менее, у меня есть еще одна проблема в том, что у меня есть «дублирующие» элементы, в которых поле value одинаково. Я не хочу этого.

Что такое элегантный способ удаления дубликатов? Или, что еще лучше, что такое элегантный способ вставки только не дубликатов?

Я не был достаточно ясен ранее о дублирующей проблеме. Дело в том, что разные предметы должны иметь разные имена, например. ITEM1, ITEM2 и т. Д .; иначе они заменяют друг друга. Я хочу сравнить их value.

Было бы лучше/проще, если бы я хранил данные в другой структуре? Я думаю, если, возможно, FIELD3 следует заменить на ArrayList вместо Object. В настоящее время это похоже на следующее, из которого я хочу удалить дубликаты фруктов с полями «WATERMELON».

FRUITS 
    > FRUIT1 
     > WATERMELON 
     > BIG 
    > FRUIT2 
     > WaTeRMeLON 
     > BIG 
    > FRUIT3 
     > APPLE 
     > SMALL 

Пожалуйста, помогите!

+0

Я обновил свое сообщение, чтобы уточнить мою новую проблему. Вы можете помочь? @ Взрывоопасные таблетки – Tacocat

+0

Nvm! Я понял это, ха-ха! @ Explosion Pills – Tacocat

ответ

1

Мне удалось решить мою проблему, не дублируюсь, изменив структуру хранилища данных. В случае, если кто-то заинтересован ...

// Creating an ArrayList to store all the different fruits 
ArrayList<BasicDBObject> newField = new ArrayList<BasicDBObject>(); 
for (...) { 
    String value = ""; 
    String type = ""; 
    BasicDBObject newItem = new BasicDBObject("value", value).append("type", type); 
    newField.add(newItem); 
} 

// Removing duplicates from ArrayList 
Set<BasicDBObject> setItems = new LinkedHashSet<BasicDBObject>(newField); 
newField.clear(); 
newField.addAll(setItems); 

// Adding ArrayList of fruits into database 
BasicDBObject update = new BasicDBObject(); 
update.put("$set", new BasicDBObject("FRUITS", newField)); 
WriteResult result = coll.update({"_id":"1"}, update, true, false); 

Примечание: Использование LinkedHashSet вместо HashSet означает, что сохраняется порядок.

1

This post говорит, что для каждого объекта, который вы хотите создать, используется отдельный BasicDBObject. Это многословие, но я не нашел другого способа сделать это.

BasicDBObject item1 = new BasicDBObject("STR1", "text").append("STR2", "txt"); 
// also for item2 and item3... 

BasicDBObject field3 = new BasicDBObject("ITEM1", item1).append("ITEM2", item2); 

update.put("$set", new BasicDBObject("FIELD3", field3)); 
+0

OK. Nvm. Я должен уметь адаптировать это, чтобы получить то, что мне нужно. Попробуем позже, спасибо! – Tacocat

Смежные вопросы