I am using the mongo-db java driver 3.8 and work with the collection as follows:
MongoDatabase md=mongoClient.getDatabase(databaseName);
MongoCollection<ConstructionPlan> collection=md.getCollection(plansCollectionName,abc.class);
collection.insertOne(item);
collection.find(Filters.eq("itemId", id),abc.class).first();
With this code I do not have to do any conversion. I was looking for a way to update an document the same way. I am thinking on something like this:
abc anABCObject=collection.find(Filters.eq("itemId", id),ConstructionPlan.class).first();
//updates...
collection.update(anABCObject);
Is there a way to update an existing document without BSON conversion? (I was unable to find it....)
updateOne for updating document fields using update operators.
You need replaceOne which takes the replacement document.
collection.replaceOne(
Filters.eq("itemId", id),
anABCObject
);
Related
I am implementing a process in rust where I read a large number of documents from a mongodb collection, perform some calculations on the values of each document and then have to update the documents in mongodb.
In my initial implementation, after the calculations are performed, I go through each of the documents and call db.collection.replace_one.
let document = bson::to_document(&item).unwrap();
let filter = doc! { "_id": item.id.as_ref().unwrap() };
let result = my_collection.replace_one(filter, rec_document, None).await?
Since this is quite time consuming for large record sets, I want to implement it using db.collection.bulkWrite. In version 1.1.1 of the official rust mongodb driver, bulkWrite does not seem to be supported, so I want to use db.run_command. However, I am not sure how to call db.collection.bulkWrite(...) using run_command as I cannot figure out how to pass the command name as well as the set of documents to replace the values in mongodb.
What I have attempted is to create a String representing the command document with all the document records to be updated string joined as well. In order to create bson::Document from that string, I convert the string to bytes and then attempt to create the document to be passed using Document::from_reader but that doesn't work, nor is a good solution.
Is there a proper or better way to call bulkWrite using version 1.1.1 of the mongodb crate?
I've written an operation upsert a document to Mongo using Morphia.
I have a field which I want to save as an int32, but after the upsert it is inserted as int64.
I have made sure that I convert the long as an int using Long.intValue() and the object that Morphia serializes back to, the member field is int. I have also checked the UpdateOperations.ops to see what morphia is upserting.
The upsert operation is:
UpdateOperations<Test> ops = datastore.createUpdateOperations(Test.class)
.set("test_field", testField.intValue())
The current version of Mongo I am using is 3.0.
Any help would be appreciated!
Thanks!
EDIT:
Looking at the update query operation in Morphia it is:
{$set={test_field=11}}
I managed to find out the solution. The query for the upsert was querying on the test_field as a long rather than an int. Mongo 3.0 sees this as the type to insert - however running on Mongo 3.2, there is no issue and it will upsert with the type specified in the upsert operation, not the query.
I am currently in the process of refactoring some of our mongo querying code to get rid of methods deprecated in Morphia 1.3. I am running into an issue when trying to run a find and Modify query with an index . At the moment our legacy code is setting an index on the query in this fashion:
ds.createQuery(Entity.class).hintIndex("index")
I have removed it to be in line with morphia 1.3 and the code now looks something like this :
new FindOptions.modifier("$hint", "index");
return query.asList(findOptions);
As a result we do not set the index on the query until actually running it. This is fine of get queries, less so for upsert ones.
To replace the deprecated findAndModify : findAndModify(Query<T> query, UpdateOperations<T> operations, boolean oldVersion, boolean createIfMissing), morphia is asking to use findAndModify(Query, UpdateOperations, FindAndModifyOptions)
In this case, I would have expected to have a modifier method in the FindAndModifyOptions object to be able to set an index, when running the query. I can't seem to be able to do something like this:
FindAndModifyOptions findOptions = new FindOptions();
findOptions.modifier("$hint", SUGGESTION_CONTENT_TYPE_INDEX_NAME);
return datastore.findAndModify(query, updateOperations, findAndModifyOptions);
Can someone advise on how to pass the index? Is it possible to do it via the FindAndModifyOptions object ?if not, what would be the best way to set the index for the upsert query
I understand the fact that you can't update _id on an existing mongodb document.
But is there a reason that we can't use it in an upsert in the 'setOnInsert' part ? Because it is 'on insert' so it's not an update.
My expected usage is this:
db.myCol.update({_id:12345},{$setOnInsert:{_id:12345},$set:{myValue:'hi'}});
Is this a bug or am i missing something ?
MongoDB uses the 'query' part for an upsert query as part of the set, meaning that you don't have to specify the _id in the set part of you want to specify your own _id.
note: my query above also had a small bug which was the missing upsert flag.
This is the correct query:
db.myCol.update({_id:12345},{$set:{myValue:'hi'}},{upsert:true});
If the record doesn't exist, this query will insert a record which looks like this:
{_id:12345,myValue:'hi'}
Really, this is a bug in mongo fixed in development version 2.5.4 or release 2.6.0:
https://jira.mongodb.org/browse/SERVER-9958
Once that's fixed, I believe this should work as desired. In the general case, the query for update won't necessarily specify an "_id" field.
I have a Rails 3 app using MongoDB, with Mongoid as the ORM. I'd like to query for a specific field within a collection.
To query for all records of a particular collection I use User.all.to_a, as an equivalent to User.all in ActiveRecord.
Now I'd like to query for all records within a collection, but only output a particular field. In this case I'd like to see all User names. How do I do this?
I'm sure I've stared right at this in the Mongoid documentation and am just missing something...
I couldn't locate it in the new documentation for mongoid, but here is a quick link to only pointing to old 2.x.x documentation.
Basically you need to do:
User.all.only(:name).to_a