3

im new to MongoDB and completely confused by the queries. I simply need to update a document in a mongodb database by adding a string value (example: Temperature) to a list of strings. From research I know that I have to use the $push method for that. I think the code has to look somehow like this:

BasicDBObject newDocument = new BasicDBObject().append("$set", 
new BasicDBObject().append("Subscribed Topics", topic));

collection.update(new BasicDBObject().append("Sensor Type", sensorType), newDocument);
new BasicDBObject("$push",
new BasicDBObject("Subscribed Topics", topic));

The field with the array is called "Subscribed Topics", "topic" is a String (Temperature). Then I want to update the document in the collection with the corresponding "Sensor Type". However, I do not really know how to call the $push part correctly. I hope someone can help me sort this part of the code.

Best regards.

Update, I tried to implemented as suggested in the duplicate question but still got error. Very unsure if thats the right way anyway.

 DBObject listItem = new BasicDBObject("Subscribed Topics", "Light");
             DBObject updateQuery = new BasicDBObject("$push", listItem);
             collection.update(query, updateQuery);`

I create a new Object with the value Light in for Key Subscribed Topics (the array). Why do I push it to a new Object then?

Julian Herbold
  • 537
  • 9
  • 20
  • Possible duplicate of [(MongoDB Java) $push into array](https://stackoverflow.com/questions/15436542/mongodb-java-push-into-array) – dnickless Jul 26 '17 at 19:38
  • I saw that post. its almost the same. Eventhoug my array structure is more simple I dont get how to adapt it to my use case. – Julian Herbold Jul 26 '17 at 20:01
  • 1
    Next one that might help (mind you, they're using a proper business object here, plus they're only creating not changing stuff so forget it - I'm sorry): https://stackoverflow.com/questions/15371839/how-to-add-an-array-to-a-mongodb-document-using-java (I suppose, you've been looking through StackOverflow already quite a bit yourself) – dnickless Jul 26 '17 at 20:09
  • 1
    I'm only using the C# version of the driver which works differently, but have you tried this: `collection.update(eq("Sensor Type", sensorType), push("Subscribed Topics", topic))`? Also, could you perhaps share your data structures and the desired result? – dnickless Jul 26 '17 at 20:27
  • 1
    ...or rather using `updateOne` instead of just `update`. – dnickless Jul 26 '17 at 20:36
  • collection.update(eq("Sensor Type", sensorType), push("Subscribed Topics", topic)) is not working it does not know eq – Julian Herbold Jul 27 '17 at 13:14
  • 1
    Try adding an import of com.mongodb.client.model.Updates, no, hold on, wrong namespace, just a second, use com.mongodb.client.model.Filters as per http://mongodb.github.io/mongo-java-driver/3.4/javadoc/?com/mongodb/client/model/Filters.html#eq-java.lang.String-TItem- – dnickless Jul 27 '17 at 15:02
  • I added ihe import. Now eq is recognized. But after there is an error for push: its says "The method push(String, String) is undefined for the type Connector" – Julian Herbold Jul 27 '17 at 15:28
  • 1
    Add the first import, too, that I mentioned above as per http://api.mongodb.com/java/current/com/mongodb/client/model/Updates.html#push-java.lang.String-TItem- – dnickless Jul 27 '17 at 16:02
  • Im confused. I added "import static com.mongodb.client.model.Filters.*;" I thought this includes all the stuff mentioned on the website – Julian Herbold Jul 27 '17 at 16:32
  • 1
    com.mongodb.client.model.Updates is missing, it's two different websites... – dnickless Jul 27 '17 at 16:44
  • oh sorry. I added both import static com.mongodb.client.model.Filters.*; and import com.mongodb.client.model.Updates; | Still it says "The method push(String, String) is undefined for the type Connector" – Julian Herbold Jul 27 '17 at 16:51
  • 1
    Try import static com.mongodb.client.model.Updates.*; – dnickless Jul 27 '17 at 17:28
  • well I did now it is saying "The method update(DBObject, DBObject) in the type DBCollection is not applicable for the arguments (Bson, Bson)" appreciate your help though :D – Julian Herbold Jul 27 '17 at 19:26
  • Does updateOne work? – dnickless Jul 27 '17 at 19:34
  • unfortunately not; The method updateOne(Bson, Bson) is undefined for the type DBCollection – Julian Herbold Jul 27 '17 at 19:37

2 Answers2

2

My goodness! This question got me descending into the long forgotten world of Java again - after all these years... ;) Anyhoo, here's a complete working example that might give you a clue of what's going on. You can run the code several times and see how the number of elements in the "Subscribed Topics" array increases.

I used the following driver: https://oss.sonatype.org/content/repositories/releases/org/mongodb/mongo-java-driver/3.3.0/mongo-java-driver-3.3.0.jar

import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;

import org.bson.Document;
import org.bson.conversions.Bson;

import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Updates.*;

public class MongoDbPush {
  public static void main(String[] args)
  {
    MongoClient mongoClient = new MongoClient();
    MongoDatabase database = mongoClient.getDatabase("pushExampleDb");
    MongoCollection<Document> collection = database.getCollection("pushExampleCollection");

    String sensorType = "Temperature";

    // try to load existing document from MongoDB
    Document document = collection.find(eq("Sensor Type", sensorType)).first();
    if(document == null)
    {
      // no test document, let's create one!
      document = new Document("Sensor Type", sensorType);

      // insert it into MongoDB
      collection.insertOne(document);

      // read it back from MongoDB
      document = collection.find(eq("Sensor Type", sensorType)).first();
    }

    // see what it looks like in JSON (on the first run you will notice that it has got an "_id" but no "Subscribed Topics" array yet)
    System.out.println(document.toJson());

    // update the document by adding an entry to the "Subscribed Topics" array
    Bson filter = eq("Sensor Type", sensorType);
    Bson change = push("Subscribed Topics", "Some Topic");
    collection.updateOne(filter, change);

    // read one more time from MongoDB
    document = collection.find(eq("Sensor Type", sensorType)).first();

    // see what the document looks like in JSON (on the first run you will notice that the "Subscribed Topics" array has been created and has got one element in it)
    System.out.println(document.toJson());

    mongoClient.close();
  }
}
dnickless
  • 10,733
  • 1
  • 19
  • 34
  • It works fine for my case, thanks a lot ! No I need to check if the topic is already available but I am going to find that out by myself ;) (addToSet) – Julian Herbold Jul 28 '17 at 10:14
0

The above method still works, however, with updated Mongo Driver the below is also a viable mechanism.

The below works for Mongo Driver 3.6 onward (in this case using 3.12.4)

MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("pushExampleDb");
MongoCollection<Document> collection = database.getCollection("pushExampleCollection");

collection.findOneAndUpdate(Filters.eq("Sensor Type",<theSensorTypeNameComesHere>), 
                            Updates.pushEach("Subscribed Topics",<listContainingTheValuesComeHere>));

Refer: $push and $each from MongoDB Manual

Ironluca
  • 3,402
  • 4
  • 25
  • 32