How to handle EOF error from mgo in Golang - mongodb

Rarely I see a EOF error from mgo in my logs. Searching about this issue I came across this discussion where it is suggested that it would be safe to put a session.Refresh() at the start of the loop to handle this issue other issues like socket error, timeout etc.
However I couldn't find if my loop should be like this where the collection (*mgo.Collection) is re-assigned after each Refresh():
session := // create mgo session
var collection *mgo.Collection
for{
session.Refresh()
collection := session.DB("dbname").C("collectionName")
....
}
OR like below where collection is assigned once outside the loop:
session := // create mgo session
collection := session.DB("dbname").C("collectionName")
for{
session.Refresh()
....
}
Posting this since I am not able to simulate this issue at will

Related

Golang take nested value from mongo.SingleResult

In Golang I read a value from a database.
findOptions := options.FindOneOptions{}
findOptions.SetSort(bson.D{{"foo", -1}})
var valueFromDatabase *mongo.SingleResult
valueFromDatabase = clients.MongoClient.Database("foo").Collection("foo").FindOne(context.TODO(), bson.M{})
Is it possible to get a specific position, much like you would in an array?
Not working sample code, how it should fetch the values:
valueFromDatabase.NestedObject.Array[0].Value
Background is. A generic approach should be used so that the solution works independently of the structure of the BSON document. Which fields are to be read out is known from a slice.
The following approach was tried: The conversion to a json destroys the Mongo encryption.

I can Find a record with MongoDB official Golang drivers, but the record is empty

I'm trying to learn Go and I wrote a little code that handles a MongoDB test database, inserting some general "items".
This is the code:
https://pastebin.com/ptNwKbk2
I can insert and update records without issues but when I try to FindOne or Find a record what comes out is some empty shell, it finds the record but the record only shows its id.
First Find [line 89]:
err = collection.FindOne(context.TODO(), filter).Decode(&resultItem)
Result:
Found a single document: {ID:ObjectID("5cb488c30eeb652e64ecdaeb") itemID: priority:0 desc:}
Second Find [line 95]:
cur, err := collection.Find(context.TODO(), emptyFilter, findOptions)
Result, every element has an id but no data inside ("itemID: priority:0 desc:"):
Found multiple documents (array of pointers): [0xc00004c840 0xc00004c8c0]
Could someone find what the problem is here?
Thanks in advance
The members of Items must start with an uppercase letter (just the variable names, the json/bson tags are fine) otherwise the deserializer can't access them.

How to set batchSize in change stream watch api (mongo-go-driver)?

I am passing batchSize using changestreamopt.BatchSize.
But this not working this error occurred: BSON field '$changeStream.batchSize' is an unknown field
Sample API call
// coll is *mongo.Collection
// ctx is context
cur, err := coll.Watch(ctx, nil, changestreamopt.BatchSize(1000))
This looks like a bug in the current mongo-go-driver (v0.0.16) where the batchSize option is passed into the $changestream pipeline stage instead to the cursor.
The code change_stream.go#L66-L73 seems to only use maxAwaitTime to the cursor.
I've opened a ticket GODRIVER-591 with the MongoDB Go driver team.

Pymongo sort error

I have been trying to sort documents in Mongo collection by ObjectId in descending order from Pymongo and use the last added record using this code
record = collection.find({}).sort('_id', -1).limit(1)
However, I am getting 'expected a character buffer object'error. Not sure what is happening here.
Also, if anyone can think of a better way to get the last added record from mongo collection using Pymongo, it will be great help.
for item in collection.find().sort("_id", pymongo.DESCENDING).limit(1):
# do something with your item.
This error indicates to me that your "collection" variable holds a string, not a PyMongo Collection instance. I need to see the code that sets the "collection" variable to know what mistake you're making. But let's start from the top:
import pymongo
client = pymongo.MongoClient()
collection = client.db
cursor = collection.find({}).sort('_id', -1).limit(1)
record = cursor.next()
This will get you a recently-added document, but not always the most recently added. The timestamp portion of an ObjectId is only precise to one second, and since it's generated on the client machine that inserts the document, ObjectId is subject to clock skew.
If and only if the collection is capped, you can reliably get the last document like:
cursor = collection.find({}).sort('$natural', -1).limit(1)
record = cursor.next()

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.