For example, I am modeling a family below with kids which have toys.
I can never add more than one kid or toy
(I HAVE OMITTED ID ATTRIBUTES TO KEEP SHORT, THEY ARE ALL UNIQUE IN MY
ACTUAL SCENARIO)
{
"name" : "John Doe",
"age" : "40"
}
I want to add values to an array that may not exist.
This works as expected from the shell:
db.users.update({'users.name': 'John Doe'},{$addToSet : {'kids' :
{ 'name' : 'Bob', 'age': '4'}}})
db.users.update({'users.name': 'John Doe'},{$addToSet : {'kids' :
{ 'name' : 'Dan', 'age': '2'}}})
Results in:
{
"name" : "John Doe",
"age" : "40",
"kids" : [
{
"name" : "Bob",
"age" : "4"
},
{
"name" : "Dan",
"age" : "2"
}
]
}
The java api is overriding the previous entry when I attempt to
express the same thing.
I am sure I have something wrong, but I am not sure what. Please see
below.
EXECUTION #1:
BasicDBObject kidBob = new BasicDBObject();
kids.put("name","Bob");
kids.put("age","4");
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids", kidBob));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
usersCollection.update(userMatch, userMod);
This results in:
{
"name" : "John Doe",
"age" : "40",
"kids" : [
{
"name" : "Bob",
"age" : "4"
},
]
}
EXECUTION #2:
BasicDBObject kidDan = new BasicDBObject();
kids.put("name","Dan");
kids.put("age","2");
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids", kidDan));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
usersCollection.update(userMatch, userMod);
This results in:
{
"name" : "John Doe",
"age" : "40",
"kids" : [
{
"name" : "Dan",
"age" : "2"
}
]
}
Any ideas why it is not appending to the array as expected????
I have the same issue for a nested array:
db.users.update({'users.name': 'John Doe', 'users.kids.name' : 'Bob'},
{$addToSet : {'users.$.toys' : { 'type' : 'Truck', 'color' :
'blue'}}})
BasicDBObject toyDan = new BasicDBObject();
kids.put("type","Truck");
kids.put("color","blue");
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids.$.toys", toyDan));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
userMatch.put("kids.name","Dan");
usersCollection.update(userMatch, userMod);
{
"name" : "John Doe",
"age" : "40",
"kids" : [
{
"name" : "Dan",
"age" : "2"
"toys" : [
{
"type" : "Truck",
"color" : "blue"
}
]
}
]
}
Adding another toy just replaces the previous toy.
How do I get the behavior I want???
> BasicDBObject kidBob = new BasicDBObject();
> kids.put("name","Bob");
> kids.put("age","4");
kids should be kidBob...
> --
> You received this message because you are subscribed to the Google Groups "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
>
>
It should have been:
BasicDBObject kidBob = new BasicDBObject();
kidsBob.put("name","Bob"); // fixed this
kidsBob.put("age","4"); // fixed this
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids", kidBob));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
usersCollection.update(userMatch, userMod);
AND
BasicDBObject kidBob = new BasicDBObject();
kidBob.put("name","Bob"); // fixed this
kidBob.put("age","4"); // fixed this
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids", kidBob));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
usersCollection.update(userMatch, userMod)
AND
BasicDBObject toyDan = new BasicDBObject();
toyDan.put("type","Truck"); // fixed this
toyDan.put("color","blue"); // fixed this
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids.$.toys", toyDan));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name","John Doe");
userMatch.put("kids.name","Dan");
usersCollection.update(userMatch, userMod);
Is the way this intended to be used? I thought I may have been doing
something wrong.
If you paste a full .java that you run that reproduces the error, can
you send the entire file.
OUTPUT:
WITH THE SECOND SAVE:
> db.users.find()
{ "_id" : "John Doe", "age" : "40", "kids" : [ { "_id" : "Bob",
"name" : "Bob", "age" : "4" } ], "name" : "John Doe" }
WITHOUT THE SECOND SAVE:
> db.users.find()
{ "_id" : "John Doe", "age" : "40", "kids" : [
{
"_id" : "Dan",
"age" : "2",
"name" : "Dan",
"toys" : [
{
"_id" : "Truck",
"type" : "Truck",
"color" : "blue"
},
{
"_id" : "Car",
"type" : "Car",
"color" : "Red"
}
]
},
{
"_id" : "Bob",
"name" : "Bob",
"age" : "4"
}
], "name" : "John Doe" }
CODE:
import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
public class Test
{
public static void main(String[] args) throws Exception
{
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("test");
DBCollection usersCollection = db.getCollection("users");
BasicDBObject user = new BasicDBObject();
user.put("_id", "John Doe");
user.put("name", "John Doe");
user.put("age", "40");
usersCollection.save(user);
// START TEST 1
System.out.println("Start Test 1");
BasicDBObject kidDan = new BasicDBObject();
kidDan.put("_id", "Dan");
kidDan.put("name", "Dan");
kidDan.put("age", "2");
BasicDBObject userMod = new BasicDBObject();
userMod.put("$addToSet", new BasicDBObject("kids", kidDan));
BasicDBObject userMatch = new BasicDBObject();
userMatch.put("name", "John Doe");
usersCollection.update(userMatch, userMod);
// START TEST 2
System.out.println("Start Test 2");
BasicDBObject toyDan = new BasicDBObject();
toyDan.put("_id", "Truck");
toyDan.put("type", "Truck");
toyDan.put("color", "blue");
BasicDBObject userMod2 = new BasicDBObject();
userMod2.put("$addToSet", new BasicDBObject("kids.$.toys", toyDan));
BasicDBObject userMatch2 = new BasicDBObject();
userMatch2.put("name", "John Doe");
userMatch2.put("kids.name", "Dan");
usersCollection.update(userMatch2, userMod2);
/************************************
* THIS FOLLOWING LINE IS CAUSING THE PROBLEM
* I AM EXECUTING THIS IN A LOOP WHICH RESULTS
* IN THE SAME USER EXISTING MULTIPLE TIMES
* I WANT TO UPDATE THE USER IF IT IS DIFFERENT
* I UNDERSTOOD THAT SAVE MADE THE DISTINCTION
* BETWEEN INSERT AND UPDATE
***********************************/
usersCollection.save(user);
// START TEST 3
System.out.println("Start Test 3");
BasicDBObject kidBob = new BasicDBObject();
kidBob.put("_id", "Bob");
kidBob.put("name", "Bob");
kidBob.put("age", "4");
BasicDBObject userMod3 = new BasicDBObject();
userMod3.put("$addToSet", new BasicDBObject("kids", kidBob));
BasicDBObject userMatch3 = new BasicDBObject();
userMatch3.put("name", "John Doe");
usersCollection.update(userMatch3, userMod3);
// START TEST 4
System.out.println("Start Test 4");
BasicDBObject toy2Dan = new BasicDBObject();
toy2Dan.put("_id", "Car");
toy2Dan.put("type", "Car");
toy2Dan.put("color", "Red");
BasicDBObject userMod4 = new BasicDBObject();
userMod4.put("$addToSet", new BasicDBObject("kids.$.toys",
toy2Dan));
BasicDBObject userMatch4 = new BasicDBObject();
userMatch4.put("name", "John Doe");
userMatch4.put("kids.name", "Dan");
usersCollection.update(userMatch4, userMod4);
It makes no sense in the scenario, but imagine I am loading from
a file with duplicate users. Test 1 & 2 occur at the same time but
3 & 4 occur in a different iteration of the loop. I need to create or
update the user as appropriate.
I am starting to think save does not act how I expect.
How do I update the existing user?
> ...
>
> read more »
import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
public class Test
{
public static void main(String[] args) throws Exception
{
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("test");
DBCollection usersCollection = db.getCollection("users");
BasicDBObject user = new BasicDBObject();
user.put("_id", "John Doe");
user.put("name", "John Doe");
user.put("age", "40");
BasicDBObject userSearch = new BasicDBObject();
userSearch.put("name", "John Doe");
usersCollection.update(userSearch,user,true,false);
usersCollection.update(userMatch, userMod);
usersCollection.update(userMatch2, userMod2);
***********************************/
//usersCollection.save(user);
usersCollection.update(userSearch,user,true,false);
usersCollection.update(userMatch3, userMod3);
usersCollection.update(userMatch4, userMod4);
}
}
> ...
>
> read more »
You should walk through line by line seeing what each does. I don't
quite think you get what does what
>>>>> $.toys", toyDan));
>>
>>>>> BasicDBObject userMatch2 = new BasicDBObject();
>>>>> userMatch2.put("name", "John Doe");
>>>>> userMatch2.put("kids.name", "Dan");
>>
>>>>> usersCollection.update(userMatch2, userMod2);
>>
>>>>> /************************************
>>>>> * THIS FOLLOWING LINE IS CAUSING THE PROBLEM
>>>>> * I AM EXECUTING THIS IN A LOOP WHICH RESULTS
>>>>> * IN THE SAME USER EXISTING MULTIPLE TIMES
>>>>> * I WANT TO UPDATE THE USER IF IT IS DIFFERENT
>>>>> * I UNDERSTOOD THAT SAVE MADE THE DISTINCTION
>>>>> * BETWEEN INSERT AND UPDATE
>>>>> ***********************************/
>>>>> usersCollection.save(user);
>>
>>>>> // START TEST 3
>>>>> System.out.println("Start Test 3");
>>
>>>>> BasicDBObject kidBob = new BasicDBObject();
>>>>> kidBob.put("_id", "Bob");
>>>>> kidBob.put("name", "Bob");
>>>>> kidBob.put("age", "4");
>>
>>>>> BasicDBObject userMod3 = new BasicDBObject();
>>>>> userMod3.put("$addToSet", new BasicDBObject
>>>>> ("kids", kidBob));
>>
>>>>> BasicDBObject userMatch3 = new BasicDBObject();
>>>>> userMatch3.put("name", "John Doe");
>>
>>>>> usersCollection.update(userMatch3, userMod3);
>>
>>>>> // START TEST 4
>>>>> System.out.println("Start Test 4");
>>
>>>>> BasicDBObject toy2Dan = new BasicDBObject();
>>>>> toy2Dan.put("_id", "Car");
>>>>> toy2Dan.put("type", "Car");
>>>>> toy2Dan.put("color", "Red");
>>
>>>>> BasicDBObject userMod4 = new BasicDBObject();
>>>>> userMod4.put("$addToSet", new BasicDBObject("kids.
Thanks for your time and help. Nice product!
On Apr 12, 6:17 pm, Eliot Horowitz <eliothorow...@gmail.com> wrote:
> You're doing a replace...
>
> You should walk through line by line seeing what each does. I don't
> quite think you get what does what
>
> ...
>
> read more »
save replaces the object whereas update with $-ops modifies individual fields.
On Apr 12, 2010 6:06 PM, "Wes" <wwwe...@gmail.com> wrote:
I agree. I am confused. I specified the _id when using save, so I
thought it would upsert the object reference by the id. When using
update, I thought it would search for the first object and upsert with
the second. That seems to be what the documentation indicates. I
definitely need to play around some more from the shell.
Thanks for your time and help. Nice product!
On Apr 12, 6:17 pm, Eliot Horowitz <eliothorow...@gmail.com> wrote: > You're doing a replace... > ...
> On Apr 12, 2010, at 5:49 PM, Wes <wwwest...@gmail.com> wrote: > > > > > OK. Same result though. Wh...
> ... > > read more » -- You received this message because you are subscribed to the Google Groups...