CosmosDB latency after insert using mongodb api - azure-cosmosdb-mongoapi

We have a C# method that will insert a document into CosmosDB (mongoDB Api) and then immediately perform a find for that document and its about 50/50 that it returns the document. It seems as if it is not fully completed in inserting the document even though it returns success. If the same find is ran again, it finds the document immediately. Has anyone else had these issues?
Here is our method..
newFederatedUser.Email = newFederatedUser.Email.ToLower();
FederatedUsers.InsertOne(newFederatedUser);
return FederatedUsers.Find(x => x.Email == newFederatedUser.Email).SingleOrDefault() != null;

Related

Silent insertion failure in MongoDB

I have a mongodb instance running and I need to change the '_id' field of each document.
Therefore I retrieve documents that need to changed, modified the '_id', inserted the modified documents, and deleted the original document. Everything succeeds, but I am unable to see the change in the database.
doc_id = doc['_id']
inserted = db.candidates.insert_one(doc)
deleted = db.candidates.delete_one({'_id': doc_id})
res = list(db.candidates.find({'_id': inserted.inserted_id}))
assert len(res) >= 1, 'could not retrieve inserted document'
The assertion on line 4 fails for every document. And I can find the deleted document in the database even though the DeleteResult reports that it was deleted.
{'n': 1, 'ok': 1.0}
I have been unable to find anything in the Pymongo documentation about this issue and I have been unable to find similar problems online. Am I missing something obvious?
Modification of other collections and fields seems to work fine.
You're inserting the document, then deleting the same document. That's why your find doesn't return any records.

How to avoid mongo from returning duplicated documents by iterating a cursor in a constantly updated big collection?

Context
I have a big collection with millions of documents which is constantly updated with production workload. When performing a query, I have noticed that a document can be returned multiple times; My workload tries to migrate the documents to a SQL system which is set to allow unique row ids, hence it crashes.
Problem
Because the collection is so big and lots of users are updating it after the query is started, iterating over the cursor's result may give me documents with the same id (old and updated version).
What I'v tried
const cursor = db.collection.find(query, {snapshot: true});
while (cursor.hasNext()) {
const doc = cursor.next();
// do some stuff
}
Based on old documentation for the mongo driver (I'm using nodejs but this is applicable to any official mongodb driver), there is an option called snapshot which is said to avoid what is happening to me. Sadly, the driver returns an error indicating that this option does not exists (It was deprecated).
Question
Is there a way to iterate through the documents of a collection in a safe fashion that I don't get the same document twice?
I only see a viable option with aggregation pipeline, but I want to explore other options with standard queries.
Finally I got the answer from a mongo changelog page:
MongoDB 3.6.1 deprecates the snapshot query option.
For MMAPv1, use hint() on the { _id: 1} index instead to prevent a cursor from returning a document more than once if an intervening write operation results in a move of the document.
For other storage engines, use hint() with { $natural : 1 } instead.
So, from my code example:
const cursor = db.collection.find(query).hint({$natural: 1});
while (cursor.hasNext()) {
const doc = cursor.next();
// do some stuff
}

Unable to pull ALL documents from MongoDB collection in jmeter

Unable to pull all the documents from MongoDB collection using Jmeter JSR233 sampler.
I’m trying to pull all the documents from MongoDB collection to jmeter to pass it as a test case for my performance test execution.
The below works -
myDoc = collection.find(eq("ABCValue", "ABC")).first();
log.info myDoc.toJson();
collection.find(...query...).last(); also works.
I’m able to pull the first and last value from MongoDB collection for that query. However unable to pull all the documents from the collection when I try to use the following -
myDoc = collection.find();
log.info myDoc.toJson();
This does not work only in Jmeter. Please help!
To print all documents returned from find(), you need to iterate over the documents returned
for (Document cur : collection.find()) {
log.info cur.toJson();
}
The find() method returns a FindIterable() instance that provides a fluent interface for chaining other methods.

Check if entity exists in mongo with SpringData throws exception count is not allowed in multi document transaction

I use springData and mongo 4.6. I start a transaction, update one document in one collection and then I need to check if another document in another collection exists.
#Transaction
someService() {
Object res1 = someService1DocuemntUpdate();
// It fails here.
boolean exists = anotherObjectRepository.exists(anotherObjectId);
if (exists) {
process(res1);
}
}
And I get
com.mongodb.MongoCommandException: Command failed with error 50851 (Location50851): 'Cannot run 'count' in a multi-document transaction.
Existance operation works over count operation.
Count has restrictions in multi-document transactions
The following doc describes workarounds
https://docs.mongodb.com/manual/core/transactions/#count-operation
The easiest fix is to use findBy.. != null
More smarter fix is to write agregation request.

How do you access attributes of an object queried from Mongo in Meteor

I'm pretty new to mongo in the Meteor.js framework. Here, I've queried a MongoDB object using it's ID. I'm trying to access an attribute "mana" but it returns me undefined.
var skill = Skills.find({_id:Session.get("selected_skill")});
alert(skill);//This returns me "undefined"
Skills.update(Session.get("selected_skill"), {$inc: {mana: 1}});
Could you enlighten me on the requirements of accessing attributes in mongo for meteor? Thanks
find method returns a cursor, not object nor array. To access object, you need to either fetch it from the cursor
var skill = Skills.find(Session.get('selected_skill')).fetch()[0];
or get it directly with findOne:
var skill = Skills.findOne(Session.get('selected_skill'));
Then you may use it just as any other js object:
console.log(skill.mana);
skill._cache = {cooldown: true};
Keep in mind that on client-side, collection methods like find are non-blocking. They return whatever Meteor has in cache, not necessarily what is in the server-side db. That's why you should always use them in a reactive context, or ensure that all data has been fetched before execution (don't worry about the latter until you're fluent with Meteor, start with the first way).
Also, you need to keep in mind that because of this, findOne and find.fetch may return null / empty array, even when the corresponding element is in db (but hasn't been yet cached). If you don't take that into account in your reactive functions, you'll run into errors.
Template.article.slug = function() {
var article = Articles.findOne(current_article);
if(!article) return '';
return slugify(article.title);
};
If we didn't escape from the function with if(!article), the expression article.title would raise an error in the first computation, as article would be undefined (assuming it wasn't cached earlier).
When you want to update the database from client side, you can alter only one item by a time, and you must refer to the item by its _id. This is due to security reasons. Your line for this was ok:
Skills.update(Session.get('selected_skill'), {$inc: {mana: 1}});
alert() is a function that returns undefined no matter what you feed it.
alert(42); // -> undefined
Generally, it's far better to debug with console.log than with alert.