Creating a filter in mongo-go-driver for .FindOne - mongodb

I'm trying to check a collection to see if there is at least one documents that match a specific set of values.
I've tried reading the documentation at https://github.com/mongodb/mongo-go-driver#usage, but I can't seem to find much help there. I'm pretty new to MongoDB & Go, I believe that this is more a problem of my lack of experience.
Here is a sample query from Studio 3T that I'm trying to run with mongo-go-driver:
db.getCollection("events").find(
{
"event.eventType" : "OSR",
"context.vehicleId" : NumberInt(919514),
"ts" : {
"$gte" : ISODate("2019-06-21T21:38:43.022+0000")
}
}
).limit(1);
It seems that the context.FindOne method will do what I want (and eliminating the need for the .limit(1)). I thought that it would be straight forward to "port" this to Go and the mongo-go-driver.
I can sort of make this work, for example I have the following which will find me all the OSR:
var query = &bson.D{
{"event.eventType", "OSR"},
}
result := bson.D{}
e := collection.FindOne(context.TODO(), query).Decode(&result)
This will return me one document. Now, if I want to include the vehicleId value, and I update the query to:
var query = &bson.D{
{"event.eventType", "OSR"},
{"context.vehicleId", 919514},
}
No documents are returned. I haven't bother to expand query to include the ts field yet.
I would expect at to still have at least one document returned, but nothing is showing up. Does anybody have some tips, suggestions or guidance on what I'm doing wrong (or perhaps how I can do this better)?

Not quite sure, but have you tried with bson.M instead of bson.D?
It seems like it's working for me at least.
query := &bson.M{
"event.eventType": "OSR",
"context.vehicleId": 919514,
}
Please refer to the docs for more information.
Also, like #owlwalks said, are you sure, you're in the right collection?

Related

MongoDB does not return a field

It must be a silly mistake but I can't find it.
When I run db.getCollection('communes').findOne({}),
I obtain:
{
"_id" : ObjectId("59b851a19db72301ae771c57"),
"COMMUNE" : "ALAA6",
"LIBGEO" : "ROHRBACH",
"PAYS" : "Allemagne"
}
which is fine.
But when I run db.getCollection('communes').findOne({COMMUNE: "ALAA6"}), it returns nothing!
For strange reasons, filtering on other fields work, so when I run db.getCollection('communes').findOne({LIBGEO: "ROHRBACH"}), it returns the result. Same thing filtering on "PAYS".
Adding quotes around COMMUNE, i.e. running db.getCollection('communes').findOne({"COMMUNE": "ALAA6"}) or using find instead of findOne doesn't change anything.
Any idea?
Ok, my fault. The collection has been created from an Excel export, and it seems the first column contains a strange character. Querying from the Robo3T client did not show it, but querying from Python returns:
{'LIBGEO': 'ROHRBACH',
'PAYS': 'Allemagne',
'_id': ObjectId('59b851a19db72301ae771c57'),
'\ufeffCOMMUNE': 'ALAA6'}
so obviously the \ufeffchar before COMMUNEshould be removed...

Mgo pull update not working

I am trying to achieve the following functionality with mgo library from Go:
db.artists.update(
{_id: ObjectId("534944125117082b30000001")},
{
$pull: {
studies: {
_id: ObjectId("53d53591718a522e04000001")
}
}
})
This is basically an update to artists collection where I am trying to remove a study from studies array, based on it's id field.
So in go I use:
pullQuery := &bson.M{"studies": &bson.M{"_id": bson.ObjectIdHex("53d53fd6718a521954000001")}}
err = col.Update(&bson.M{"_id": "534944125117082b30000001"}, &bson.M{"$pull": pullQuery})
But this doesn't seem to work. If I run the first version directly in RoboMongo (mongodb client utility) it is working fine, but with mgo, it doesn't seem to work. It's giving me the error: "not found".
Thank you
EDIT
The following go code was modified, and it is working just file:
err = col.UpdateId(bson.ObjectIdHex("534944125117082b30000001"), &bson.M{"$pull": pullQuery})
The ObjectId in your first $pull example does not match the go code. Are you sure you are using the right _ids?

mongodb - i cannot update with $pushAll and simple assignment at the same time

the following fails:
db.test.update({_id:102},{$pushAll:{our_days:["sat","thurs","frid"]}, country:"XYZ"}, {upsert:true})
error message: "Invalid modifier specified: country"
The correct way seems to be:
db.test.update({_id:102},{$pushAll:{our_days:["sat","thurs","frid"]}, $set:{country:"XYZ"}}, {upsert:true})
So is it the case that I cannot mix modifiers like "$pushAll" with simple assignments like field:value, in the same update document? Instead I have to use the $set modifier for simple assignments?
Is there anything in the docs that describes this behaviour?
This happens because db.test.update({_id : 1}, {country : 1}) will just change the whole document to country = 1 and thus removing everything else.
So most probably mongo being smart tells you: You want to update specific element and at the same time to remove everything (and that element as well) to substitute it with country = 1. Most probably this is not what you want. So I would rather rise an error.
Regarding the documentation - I think that the best way is to reread mongodb update.

Mongodb - query with '$or' gives no results

There is extremely weird thing happening on my database. I have a query:
db.Tag.find({"word":"foo"})
this thing matches one object. it's nice.
Now, there's second query
db.Tag.find({$or: [{"word":"foo"}]})
and the second one does not give any results.
There's some kind of magic I obviously don't understand :( What is wrong in second query?
in theory, $or requires two or more parameters, so I can fake it with:
db.Tag.find({$or: [{"word":"foo"},{"word":"foo"}]})
but still, no results.
Your second query is perfectly fine, and it should work. Though the docs says, that $or performs logical operation on array of two or more expression, but it would work for single expression also.
Here's a sample that you can see, and try out, to get it to work: -
> db.col.insert({"foo": "Rohit"})
> db.col.insert({"foo": "Aman", "bar": "Rohit"})
>
> db.col.find({"foo": "Rohit"})
{ "_id" : ObjectId("50ed6bb1a401d9b4576417f7"), "foo" : "Rohit" }
> db.col.find({$or: [{"foo": "Rohit"}]})
{ "_id" : ObjectId("50ed6bb1a401d9b4576417f7"), "foo" : "Rohit" }
So, as you can see, both your query when used for my collection works fine. So, there is certainly something wrong somewhere else. Are you sure you have data in your collection?
Okaay, server admin installed mongodb from debian repo. Debian repo had 1.4.4 version of mongodb, aandd looks like $or is simply not yet supported out there :P

How to compare 2 mongodb collections?

Im trying to 'compare' all documents between 2 collections, which will return true only and if only all documents inside 2 collections are exactly equal.
I've been searching for the methods on the collection, but couldnt find one that can do this.
I experimented something like these in the mongo shell, but not working as i expected :
db.test1 == db.test2
or
db.test1.to_json() == db.test2.to_json()
Please share your thoughts ! Thank you.
You can try using mongodb eval combined with your custom equals function, something like this.
Your methods don't work because in the first case you are comparing object references, which are not the same. In the second case, there is no guarantee that to_json will generate the same string even for the objects that are the same.
Instead, try something like this:
var compareCollections = function(){
db.test1.find().forEach(function(obj1){
db.test2.find({/*if you know some properties, you can put them here...if don't, leave this empty*/}).forEach(function(obj2){
var equals = function(o1, o2){
// here goes some compare code...modified from the SO link you have in the answer.
};
if(equals(ob1, obj2)){
// Do what you want to do
}
});
});
};
db.eval(compareCollections);
With db.eval you ensure that code will be executed on the database server side, without fetching collections to the client.