Question

I have this structure:

public class User
{
    public ObjectId Id { get; set; }
    public Location Location { get; set; }
    public DateTime LastAround {get;set;}
}

public class Location
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

I've tried a few things but I want to update User's Location and when they were last around.

Tried this:

userHelper.Collection.Update(
    Query.EQ("_id", userId),
    Update.SetWrapped<Location>("Location", new Location { Latitude = latitude, Longitude = longitude }).Set("LastAround", DateTime.UtcNow));

and this:

userHelper.Collection.Update(
    Query.EQ("_id", userId),
    Update.Set("Location.Latitude", latitude)
        .Set("Location.Longitude", longitude)
        .Set("LastAround", DateTime.UtcNow));

Nothing worked...how can I do this?

Update 4/17:

userHelper.Collection.Update(
                Query.EQ("_id", new ObjectId(userId)),
                Update
                    .SetWrapped<Location>("Location", new Location { Longitude = longitude, Latitude = latitude })
                    .Set("LastAround", DateTime.UtcNow)
            );

The lng and lat value orders seem to be very important when doing queries on them. I was doing a geonear query and getting an strange out of bounds error. If you update in the wrong order it will put lats first and then you get the error.

Was it helpful?

Solution

Both of your original Update statements should work. I wrote a small sample program to demonstrate.

After executing this Insert statement:

var userId = ObjectId.GenerateNewId();
var user = new User
{
    Id = userId,
    Location = new Location { Latitude = 1.0, Longitude = 2.0 },
    LastAround = new DateTime(2012, 4, 14, 0, 0, 0, DateTimeKind.Utc)
};
collection.Insert(user);

The document looks like this in the mongo shell:

> db.test.find()
{ "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 1, "Longitude" : 2 }, "LastAround" : ISODate("2012-04-14T00:00:00Z") }
>

After executing the first form of the Update statement:

collection.Update(
    Query.EQ("_id", userId),
    Update
        .SetWrapped<Location>("Location", new Location { Latitude = 3.0, Longitude = 4.0 })
        .Set("LastAround", new DateTime(2012, 4, 15, 0, 0, 0, DateTimeKind.Utc)));

the document looks like this:

> db.test.find()
{ "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 3, "Longitude" : 4 }, "LastAround" : ISODate("2012-04-15T00:00:00Z") }
>

And after executing the second form of the Update statement:

collection.Update(
    Query.EQ("_id", userId),
    Update
        .Set("Location.Latitude", 5.0)
        .Set("Location.Longitude", 6.0)
        .Set("LastAround", new DateTime(2012, 4, 16, 0, 0, 0, DateTimeKind.Utc)));

the document looks like this:

> db.test.find()
{ "_id" : ObjectId("4f8c5d33e447ad34b8c7ac84"), "Location" : { "Latitude" : 5, "Longitude" : 6 }, "LastAround" : ISODate("2012-04-16T00:00:00Z") }
>

So the two forms of the Update statement are working.

The full program is here:

http://www.pastie.org/3799469

OTHER TIPS

Both of your alternatives look ok.

Are you sure that your userId variable had the correct value? It could be that the Update is not finding a matching document to update.

What I ended up doing:

var userHelper = new MongoHelper<User>();
ObjectId id = new ObjectId(userId);
var user = userHelper.Collection.FindAll().Where(u => u.Id == id).Single();
user.LastAround = DateTime.UtcNow;
user.Location = new Location { Longitude = longitude, Latitude = latitude };
userHelper.Collection.Save(user);

which works. Not sure why the other way wouldn't. I suppose this is more "SQL" like although might not have the best performance. :(

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top