Displaying mongo data with Binary data - mongodb

Relatively new to mongo, more familiar with mysql. (This is all done in the shell - mongosh)
I have a collection that has Binary fields in it like this:
db> db.myColl.find()
[
{
_id: ObjectId("633c6e6af5c0fc6e55d6ad44"),
MyID: '2',
Data: Binary(Buffer.from("7b22....", "hex"), 0),
OtherFieldsFollow.......,
}
]
I've found that I can iterate over the results using a forEach loop like this:
db.myColl.find().forEach(function(x) { console.log(x.Data.toString() })
However I'm looking for something bit more global. Like in mysql I can apply transforms to each field in my select like: SELECT UNHEX(Data), MyID FROM myColl
Is there anything like that in mongo so that I can see the whole document with Data decoded to a string without having to iterate and manually console.log each field?
Slightly related, how do I index document lists returned from find()?
var docs = db.myColl.find()
msgs[0] => nothing
console.log(msgs[0]) => nothing
How do I access individual documents from a find result?

Related

conditional mongodb view based on queried value

I'm not sure this is possible, but i'd like to create a single view or at least a single query that looks in different collections based on what's being queried.
for example, if the first character is an "A" look in the "Aresults" collection, if it's a "B" look in the "Bresults" collection, etc.
I could potentially create a "A-Z" collection with just those letters, and do a $lookup from there based on a condition, but i'm not sure how to do that either.
I am aware that i could create a view with a $unionWith having all the "*results" collections, but that seems very inefficient.
Any other ideas? Is there perhaps some type of dynamic query structure within mongodb like in MySQL (couldn't find any)?
Thanks
Something like this?
const prefix = db.meta_data.findOne({field: condition}).prefix ;
db.createView('view_name', prefix + 'results', [<your aggregation pipeline>]);
or this?
const pipeline = [];
db.meta_data.find({ field: condition }).forEach(x => {
pipeline.push({ $unionWith: { coll: prefix + 'results' } });
});
db.collection.aggregate([pipeline]);

Fetch Record from mongo db based on type and ancestry field

in mongodb records are store like this
{_id:100,type:"section",ancestry:nil,.....}
{_id:300,type:"section",ancestry:100,.....}
{_id:400,type:"problem",ancestry:100,.....}
{_id:500,type:"section",ancestry:100,.....}
{_id:600,type:"problem",ancestry:500,.....}
{_id:700,type:"section",ancestry:500,.....}
{_id:800,type:"problem",ancestry:100,.....}
i want to fetch records in order like this
first record whose ancestry is nil
then all record whose parent is first record we search and whose type is 'problem'
then all record whose parent is first record we search and whose type is 'section'
Expected output is
{_id:100,type:"section",ancestry:nil,.....}
{_id:400,type:"problem",ancestry:100,.....}
{_id:800,type:"problem",ancestry:100,.....}
{_id:300,type:"section",ancestry:100,.....}
{_id:500,type:"section",ancestry:100,.....}
{_id:600,type:"problem",ancestry:500,.....}
{_id:700,type:"section",ancestry:500,.....}
Try this MongoDB shell command:
db.collection.find().sort({ancestry:1, type: 1})
Different languages, where ordered dictionaries aren't available, may use a list of 2-tuples to the sort argument. Something like this (Python):
collection.find({}).sort([('ancestry', pymongo.ASCENDING), ('type', pymongo.ASCENDING)])
#vinipsmaker 's answer is good. However, it doesn't work properly if _ids are random numbers or there exist documents that aren't part of the tree structure. In that case, the following code would work rightly:
function getSortedItems() {
var sorted = [];
var ids = [ null ];
while (ids.length > 0) {
var cursor = db.Items.find({ ancestry: ids.shift() }).sort({ type: 1 });
while (cursor.hasNext()) {
var item = cursor.next();
ids.push(item._id);
sorted.push(item);
}
}
return sorted;
}
Note that this code is not fast because db.Items.find() will be executed n times, where n is the number of documents in the tree structure.
If the tree structure is huge or you will do the sort many times, you can optimize this by using $in operator in the query and sort the result on the client side.
In addition, creating index on the ancestry field will make the code quicker in either case.

Error creating Geospatial index in MongoDB

I have a collection ('stops') with 14000 records imported from a CSV. Included in each record is some geospatial data, which I've converted into an array, so each essentially looks like this:
{
_id: ...,
// other fields
"loc": [
153.019073,
-27.467834
]
}
When I run db.stops.ensureIndex({ loc: '2d' }) it gives the error:
location object expected, location array not in correct format
I guess that something's wrong in one of the fields, but I can't figure out which one. Any ideas?
The problem was that there was a single record which wasn't imported correctly (probably an empty line at the end of the file).
To find it (and later remove it), I used the $where operator:
db.stops.find({ $where: 'typeof this.loc[0] != "number"' })

Mongodb querying document with linked id

I have a document that has an id of another document from a different collection embedded in it.
My desired result is to return (I'm using python and pymongo) the all the fields of the first collection, and all of the friends from the document that was embedded.
I understand mongo doesn't do joins and I understand I'll need to make two queries. I also don't want to duplicate my data.
My question is how to piece the two queries together in python/pymongo so I have one results with all the fields from both documents in it.
Here is what my data looks like:
db.employees
{_id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Joe Smith', title: 'junior',
manager: ObjectId("4d85c7039ab0fd70a117d730") }
db.managers
{_id: ObjectId("ObjectId("4d85c7039ab0fd70a117d730"), name: 'Jane Doe', title: 'senior manager'}
desired result
x = {_id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Joe Smith', title: 'junior',
manager: 'Jane Doe' }
Your basically doing something that Mongo does not support out of the box and would actually be more painful than using the two records separately.
Basically (in pseudo/JS code since I am not a Python programmer):
var emp = db.employees.find({ name: 'Joe Smith' });
var mang = db.managers.find({ _id: emp._id });
And there you have it you have the two records separately. You cannot chain as #slownage shows and get a merged result, or any result infact since MongoDB, from one qauery, will actually return a dictionary not the value of the field even when you specify only one field to return.
So this is really the only solution, to get the the two separately and then work on them.
Edit
You could use a DBRef here but it is pretty much the same as doing it this way, only difference is that it is a helper to put it into your own model instead of doing it youself.
If it works it should be something like:
db.managers.find({
'_id' => db->employees->find({ ('_id' : 1),
('_id': ObjectId("4d85c7039ab0fd70a117d733") }))
})
updated

How can I perform a search in mongoose where a field (which is an array) contains something?

Say I have things in database with this schema:
{
tags: [String]
}
I have tags array like this: ["tag1", "tag2"]
now I need to search in things and get only those which contains my tags.
I've searched and found the $where operator here but it's not what I need. I was wondering there should be something like
db.things.find( { $where: "this.tags.contains(<my tags somehow>)" } );
in mongo or something like this in mongoose. Any ideas?
You want $all.
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24all
Here are a couple of examples from mongoose:
https://github.com/LearnBoost/mongoose/blob/master/test/query.test.js#L396
On a side note, $where is typically not scalable.
MongoDB query syntax allows you to match an element array like that:
.find( { tags: 'tag1' } )
And, of course, it's working with Mongoose :)
Source: http://docs.mongodb.org/manual/tutorial/query-documents/#match-an-array-element