Update a collection in Mongo based on antothe collection with a "join" - mongodb

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

Related

MongoDB Morphia Update multi=true VS bulk update

I want to update 10,000 documents in a single web request. I intend to update only one field (which is indexed) in all the documents matched with some criteria with same value.
I see morphia 1.3.2 always set multi=true parameter in update call. Is it enough for updating 10,000 document? Or there are any bulk update functionality in morphia.
The following code should work for you.
Query<Entity> query = datastore.createQuery(Entity.class);
query.filter("name = ", "xxx");
UpdateOperations<Entity> updateOperations = datastore.createUpdateOperations(Entity.class).set
("yyy", 200);
UpdateResults updateResults = datastore.update(query, updateOperations, false, null);
All the documents in the collection with name = 'xxx' will now have all their 'yyy' attribute equal to 200.

How to use distinct with aggregate method for mongodb

I have some conditions and a level to check while fetching records from collection using MongoDB.
For this I am using below
def cursorOutput = dataSetCollection.find(whereObject,criteriaObject)
Which is working fine. but I want to use distinct with combination to above query.
def distinctMIdList = dataSetCollection.distinct(hierarchyField,whereObject)
Above is the query for distinct. How to combine two query.
I tried below which is not working
def cursorOutput = dataSetCollection.find(whereObject,criteriaObject).distinct("manager id")
whereObject is a condition to fetch results and criteriaObject is fields to fetch.
Distinct query is giving me result with only Manager id field but I am looking for other field also(use of criteriaObject).
Finally how to combine above two query. I searched for pipeline where $distinct is not available.
Thank you.
Map function:
var mapFunction = function() {
if(/*your criteria*/) {
emit("manager_id", this.manager_id);
}
};
Reduce Function:
var reduceFunction = function(managerFiled,values){
return Array.unique(values);
}

Remove records from Mongodb using shell

I have a simple collection populated with student data and I need to remove some records based on some parameters. I executed the following from mongoshell
for(i=0;i<200;i++) {
var rec = db.grades.find({student_id:i,type:'homework'}).sort({score:1}).limit(1)
db.grades.remove(rec)
}
Ideally it should remove lowest score of type homework for all student_ids. Apparently, only the last 2 records (student_id: 199) from the find parameter was purged and the rest still exists.
db.grades.find({student_id:10,type:'homework'}).sort({score:1}).limit(1)
{ "_id" : ObjectId("50906d7fa3c412bb040eb5a1"), "student_id" : 10, "type" : "homework", "score" : 6.094174990746648 }
Is it because of the aysnchoronous nature of JS / Mongo ? What are the other alternatives for solving the same?
rec is not a document, it is a database cursor. You need to actually get a document from it:
for(i=0;i<200;i++) {
var cur = db.grades.find({student_id:i,type:'homework'}).sort({score:1}).limit(1);
var actualDoc = cur.next();
db.grades.remove(actualDoc);
}
Otherwise, you're trying to remove documents based on cursor properties, which is not what you want. See also http://docs.mongodb.org/manual/core/read-operations/#cursors.
You need to query the collection and return all of the documents in the collection first before iterating through it e.g.
var collection = grades.find({'type':'homework'}).sort({'student_id',1, 'score':1})
Then iterate through the records in the variable 'collection' removing documents with the lowest score. You also have an issue assigning i as a value to student_id without assigning the documents in the collection. And according to your code you're iterating through the collection based on student id. You don't need to do this to iterate through the collection. Just query all records of type homework then remove based on parameters. If you need to assign the value of student_id to a variable (hint: as a parameter to remove records), just assign student_id to a variable like so:
var id = ['student_id']
Alternatively (and this is the way I did it), you could sort all the records first by student_id and then by score. The score should be sorted in descending order.
Then iterate through the collection using a for loop, and when the student_id changes remove the record. To recognise the change in student_id store that value in a variable outside the loop and inside the loop (as 2 separate variables) then update them as you loop through the collection. Then compare the variables and remove the record if the values of the variables are not equal.
var oldid=-1;
var cursor=db.grades.find({'type':'homework'}).sort({'student_id':1,'score':1});
while (cursor.hasNext()) {
var doc = cursor.next();
var id = doc['student_id'];
if (oldid!=id)
{
db.grades.remove(doc);
oldid=id;
}
}

How do I get the date a MongoDB collection was created using MongoDB C# driver?

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")

MongoDB C# offic. List<BsonObject> query issue and always olds values?

I have not clearly issue during query using two criterials like Id and Other. I use a Repository storing some data like id,iso,value. I have created an index("_id","Iso") to performs queries but queries are only returning my cursor if i use only one criterial like _id, but is returning nothing if a use two (_id, Iso) (commented code).
Are the index affecting the response or the query method are failing?
use :v1.6.5 and C# official.
Sample.
//Getting Data
public List<BsonObject> Get_object(string ID, string Iso)
{
using (var helper = BsonHelper.Create())
{
//helper.Db.Repository.EnsureIndex("_Id","Iso");
var query = Query.EQ("_Id", ID);
//if (!String.IsNullOrEmpty(Iso))
// query = Query.And(query, Query.EQ("Iso", Iso));
var cursor = helper.Db.Repository.FindAs<BsonObject>(query);
return cursor.ToList();
}
}
Data:
{
"_id": "2345019",
"Iso": "UK",
"Data": "Some data"
}
After that I have Updated my data using Update.Set() methods. I can see the changed data using MongoView. The new data are correct but the query is always returning the sames olds values. To see these values i use a page that can eventually cached, but if add a timestamp at end are not changing anything, page is always returning the same olds data. Your comments are welcome, thanks.
I do not recall offhand how the C# driver creates indexes, but the shell command for creating an index is like this:
db.things.ensureIndex({j:1});
Notice the '1' which is like saying 'true'.
In your code, you have:
helper.Db.Repository.EnsureIndex("_Id","Iso");
Perhaps it should be:
helper.Db.Repository.EnsureIndex("_Id", 1);
helper.Db.Repository.EnsureIndex("Iso", 1);
It could also be related to the fact that you are creating indexes on "_Id" and the actual id field is called "_id" ... MongoDB is case sensitive.
Have a quick look through the index documentation: http://www.mongodb.org/display/DOCS/Indexes