I have a collection that I'd like to update. The field is given programmatically, so I'd like to do something like this:
var update_string = 'coordinates.lat';
var update = function(value, id, update_string) {
Collection.update({_id:id}, {$set:{update_string:value}})
}
That however does not work and just sets "update_string" to have value {{value}} in the object with _id {{id}} in the Collection. I also tried doing var update_string = "'coordinates.lat'"; to no avail.
How do I accomplish this? Thanks.
You need to set the key in your update $set parameter correctly:
var update = function(value, id, update_string) {
var update_query = {};
update_query[update_string] = value
Collection.update({_id:id}, {$set:update_query})
}
Basically without the modification above, If you used {update_string:value} you would be setting the value of update_string, not coordinates.lat.
Related
I using Mongo version 4.2
I need to update a field in one collection as based on a field from another collection, according to a joining condiiton between the to collection.
In a regualr SQL, the update would be:
UPDATE col1, col2
SET col2.entityId = col1.Entity_ID
WHERE col1.id = col2.id
and col2.type='DEVICE';
I tried a method offered in one answer, but that does not seem to work, or I did not understand it correctly:
db.col1.find().forEach(function (doc1) {
var doc2 = db.col2.findOne({ id: doc1.id },{type:"DEVICE"});
if (doc2 != null) {
doc1.Entity_ID=doc2.entityId;
db.coll01.save(doc1);
}
});
Any ideas?
Thanks,
Tamar
I have mongo DB and I am using C#.Net to interact with mongo db. C# API has methods for finding a single document and updating it at the same time. For example FindOneAndUpdateAsync.
However I couldn't find any method to find multiple documents and update them at the same time asynchronously.
The code below finding and processing each document asynchronously. How do I also update that document at the same time?
public async Task<IList<IDictionary<string, string>>> DoWork()
{
var collection = _mongoDatabase.GetCollection<BsonDocument>("units");
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Ne<string>("status", "INIT") &
(filterBuilder.Exists("isDone", false) |
filterBuilder.Eq<bool>("isDone", false));
// I want to pass this update filter to update the document. But not sure how
var update = Builders<BsonDocument>.Update
.CurrentDate("startTime");
var sort = Builders<BsonDocument>.Sort.Ascending("startTime");
var projection = Builders<BsonDocument>.Projection
.Include("_id")
.Include("fileName"); // for bravity i have removed other projection elements
var output = new List<IDictionary<string, string>>();
// How do i pass update filter and update the document at the same time??
await collection
.Find(filter)
.Sort(sort)
.Project(projection)
.ForEachAsync((unit) =>
{
var dictionary = new Dictionary<string, string>();
Recurse(unit, dictionary);
output.Add(dictionary);
});
return output.Count > 0 ? output : null;
}
That doesn't exist in the mongo .Net api see here.
Just use a combination of Find and UpdateManyAsync.
i have this code for removing an item froma a mongofb collation
private MongoCollection<T> GetCollection()
{
connectionString = "mongodb://localhost/?safe=true";
server = MongoServer.Create(connectionString);
database = server.GetDatabase("CSCatalog");
return database.GetCollection<T>("myCollectionName");
}
public bool Delete(T entity)
{
var id = typeof(T).GetProperty("Id").GetValue(entity,null).ToString();
var query = Query.EQ("_id",id);
var finded = GetCollection().Find(query); // return null
var result= GetCollection().Remove(query, MongoDB.Driver.RemoveFlags.Single); // no errors, but don't remove
return esito.Ok; //return true but donn't remove.
}
the GetCollection() method retrive the right collection, i have tested it width debug.
In the collection there is the item that i want remove, it have the same id that i have retrived in first line.
the entity have some fields and a Objectid filed called "Id"
the type of _id you created is ObjectId class and you are trying to equate with string so its not able to remove. use
var queryId = new ObjectId(id);
Your finded variable should not be null if the .find() has returned something from your database. That it is null means that you have not found anything, and therefore nothing is to be removed.
What it looks like is happening here is that you are querying on _id for the ObjectId, while you are storing that ObjectId in the database as Id.
I need to select User Name from the collection of Users. I do it in a such way:
MongoCollection<Enums> coll = Db.GetCollection<Enums>("Users");
var query = Query.EQ("_id", id);
var res = coll.FindOne(query);
var name = res.Name;
var url = res.UserUrl; //or some more fields, not just Name
Assuming that User document can contain a lot of data, and there is no need to transfer the whole user document, how to select only a few distinct fields, using official C# driver?
You'll have to use a function that returns a MongoCursor.
In the MongoCursor you can specify the fields you want to return.
var result = Db.GetCollection<Enums>("Users").FindAll();
result.Fields = Fields.Include(new [] {"Name"});;
foreach (var user in result)
{
Console.WriteLine(user.Name);
}
I need to iterate through all of the collections in my MongoDB database and get the time when each of the collections was created (I understand that I could get the timestamp of each object in the collection, but I would rather not go that route if a simpler/faster method exists).
This should give you an idea of what I'm trying to do:
MongoDatabase _database;
// code elided
var result = _database.GetAllCollectionNames().Select(collectionName =>
{
_database.GetCollection( collectionName ) //.{GetCreatedDate())
});
As far as I know, MongoDB doesn't keep track of collection creation dates. However, it's really easy to do this yourself. Add a simple method, something like this, and use it whenever you create a new collection:
public static void CreateCollectionWithMetadata(string collectionName)
{
var result = _db.CreateCollection(collectionName);
if (result.Ok)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
collectionMetadata.Insert(new { Id = collectionName, Created = DateTime.Now });
}
}
Then whenever you need the information just query the collectionMetadata collection. Or, if you want to use an extension method like in your example, do something like this:
public static DateTime GetCreatedDate(this MongoCollection collection)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
var metadata = collectionMetadata.FindOneById(collection.Name);
var created = metadata["Created"].AsDateTime;
return created;
}
The "creation date" is not part of the collection's metadata. A collection does not "know" when it was created. Some indexes have an ObjectId() which implies a timestamp, but this is not consistent and not reliable.
Therefore, I don't believe this can be done.
Like Mr. Gates VP say, there is no way using the metadata... but you can get the oldest document in the collection and get it from the _id.
Moreover, you can insert an "empty" document in the collection for that purpose without recurring to maintain another collection.
And it's very easy get the oldest document:
old = db.collection.find({}, {_id}).sort({_id: 1}).limit(1)
dat = old._id.getTimestamp()
By default, all collection has an index over _id field, making the find efficient.
(I using MongoDb 3.6)
Seems like it's some necroposting but anyway: I tried to find an answer and got it:
Checked it in Mongo shell, don't know how to use in C#:
// db.payload_metadata.find().limit(1)
ObjectId("60379be2bec7a3c17e6b662b").getTimestamp()
ISODate("2021-02-25T12:45:22Z")