How can I test, if scripting is disabled in my MongoDB - mongodb

I want to make my mongoDB more secure. I read, that I can start it with --noscripting to deny JavaScript. I tried to verify, that this is working.
When I started the DB like this
mongod --dbpath /var/lib/mongodb --noscripting --fork --logpath /var/log/mongodb/mongod.log
and then I tried to use the $where-Operator like it is described here:
http://docs.mongodb.org/manual/reference/operator/query/where/
for example:
db.myCollection.find({$where: "_id == 1"})
it is returning:
Error: error: {
"$err" : "Can't canonicalize query: BadValue no globalScriptEngine in $where parsing",
"code" : 17287
}
Is this the answer, I should expect? Or is it pointing to another failure?

This is expected behavior since the --noscripting option disables the scripting engine and all the $where operator does is JavaScript evaluation as mention in the official documentation;
Use the $where operator to pass either a string containing a JavaScript expression or a full JavaScript function to the query system. The $where provides greater flexibility, but requires that the database processes the JavaScript expression or function for each document in the collection. Reference the document in the JavaScript expression or function using either this or obj .
Also the error message is pretty clear.
..."$err" : "Can't canonicalize query: BadValue no globalScriptEngine in $where parsing"
Note the no globalScriptEngine part of the message.

Related

mongo: collection not found ReferenceError: auditoria is not defined

I'm getting this message on a very simple find command:
rs0:PRIMARY> use MPI
switched to db MPI
rs0:PRIMARY> show collections;
hes-auditoria-mpi-fhir
hes-auditoria-schemas
rs0:PRIMARY> db.hes-auditoria-mpi-fhir.find();
2021-05-20T14:20:05.502+0200 E QUERY [js] ReferenceError: auditoria is not defined :
#(shell):1:1
any ideas?
Use getCollection helper:
db.getCollection("hes-auditoria-mpi-fhir").find()
It's been added exactly for this purpose. From the docs:
db.getCollection(name)
Returns a collection or a view object that is functionally equivalent to using the db.<collectionName> syntax. The method is useful for a collection or a view whose name might interact with the mongo shell itself, such as names that begin with _ or that match a database shell method.

Aggregate pipleline Error: getMore: cursor didn't exist on server, possible restart or timeout

I am facing this issue with mongodb.
My code is something like this
for(loop) {
var cursorQuery = db.beacon_0000.aggregate([
{
$match: {
...
}
},
{
$project: {
...
}
},
{
$group: {
...
}
},
{
$sort: {
...
}
}
], {allowDiskUse: true} );
...
while(cursorQuery.hasNext()) {
var cursor = cursorQuery.next();
...
}
}
I run the above query via command and mongo shell as
$ mongo dbName file.js
After a while I get the cursor didn't exist on server error at line cursorQuery.hasNext().
In find query if I get this error, I can resolve by adding addOption(DBQuery.Option.noTimeout)
However this option does not seem to be available with aggregate
Please let me know how can I resolve or workaround this issue.
Just to provide additional update:
When say I use
var cursor = db.collection..aggregate([ ...], {allowDiskUse: true} ).addOption(DBQuery.Option.noTimeout)
I get this error
E QUERY TypeError: Object # has no method 'addOption'
However when say I use
var cursor = db.collection..find({...}, {...}).addOption(DBQuery.Option.noTimeout)
It works fine.
Checking the aggregate doc
https://docs.mongodb.com/v3.0/reference/method/db.collection.aggregate/
It says:
Returns:A cursor to the documents produced by the final stage of the aggregation pipeline operation
And then checking cursor doc
https://docs.mongodb.com/v3.0/reference/method/cursor.addOption/#cursor.addOption
There is no suggestion that aggregate cursor is different from find cursor and former does not support DBQuery.Option.noTimeout.
So is there a bug at mongodb for this. Any way to fix it or have a workaround.
Note mongodb version is 3.0
I had the same issue and solved it by setting the idle cursor timeout from default 10 minutes to 1 hour. This is configurable since mongodb 2.6.9. See:
https://jira.mongodb.org/browse/SERVER-8188
https://docs.mongodb.com/manual/reference/parameters/#param.cursorTimeoutMillis
The default cursor timeout is 600000 ms = 10 minutes. You can alter it in different ways:
on startup: mongod --setParameter cursorTimeoutMillis=<num>
or: mongos --setParameter cursorTimeoutMillis=<num>
or during operation, using the mongo shell: db.adminCommand({setParameter:1, cursorTimeoutMillis: <num>})
Mongos is not transferring the command to its mongod's of the cluster. Also the Primary does not replicate the command to its replicaSet members. Thus, you need to execute the command on every mongos and mongod where the query might run.
You have sort of answered this yourself.
Adding the option addOption(DBQuery.Option.noTimeout) will indeed fix the issue when using find because it stops the cursor from timing out and therefore it will exist when you try .hasNext()
However the cursor for aggregation does not have that option so you can't stop it from timing out unfortunately.
you can actually use : maxTimeMS
as it described in documentation:
Optional. Specifies a time limit in milliseconds for processing operations on a cursor. If you do not specify a value for maxTimeMS, operations will not time out. A value of 0 explicitly specifies the default unbounded behavior.
There is an option in mongodb documentation that you can set it no a non-negative number for the time that you want your cursor to be alive.
you can see the more detail on : documentation

Select falsey documents in Meteor

I have a Meteor collection where I want to specify a query to find all documents where an attribute is falsey. In other words, where it does not exist, null, false. In native Mongo the following syntax works:
find({category: "Cereal", showOnList: {"$ne": true}})
In this case, none of the documents have the element showOnList and therefore match my query. In Meteor (client side) I get the following error when using this syntax:
Uncaught SyntaxError: Unexpected token )
at Object.InjectedScript._evaluateOn (<anonymous>:904:140)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:837:34)
at Object.InjectedScript.evaluate
(<anonymous>:693:21)InjectedScript._evaluateOn # VM220:904InjectedScript._evaluateAndWrap # VM220:837InjectedScript.evaluate # VM220:693
Anyone else run into this problem and have a workaround? Is this a Meteor bug?
You have a typo some where here is a fully working query I just tested
Posts.find({_id: {$ne: "M6RgPgC4KbnvLxz8W"}}).fetch()
I don't know how you could create this query with one statement. This is my workaround:
find({$or: [{ showOnList: null }, {showOnList: false}, {showOnList: {$exists: false}}] })

Unable to access MongoDB collection from shell when the name contains '-'

I have a collection named GoldenGlobes-emotion in my MongoDB 2.6.9
I found I can not access this collection from the MongoDB shell
When ever I try to access the collection, for example
db.GoldenGlobes-emotion.findOne()
I always got this:
ReferenceError: emotion is not defined
But it works well when I access the collection form Python with PyMongo.
Is this a shell bug?
Or '-' is a reserved character?
Try db["GoldenGlobes-emotion"].findOne().
The MongoDB shell is a Javascript interpreter. Javascript does not allow hyphens in variable names, because it interprets them as the minus-operator. However, you can also access object-fields with string literals by using the array-syntax. In that case, this restriction does not apply.

Can I remove documents of mongodb using regex expression?

I have not find a method to do it yet.
If we can not remove documents using regex expression, what can we do to make it done? And why does not mongodb provide such a driver ?
The .remove() method just takes a query object, so regular expressions are just a standard query for MongoDB:
db.collection.remove({ "field": /^string/ })
Removes anything that has "field" that starts with "string"
Look at the documentation for $regex as well.
Documents can be remove using remove() method and $regex query.
For example
db.users.remove({"email" : { $regex : /$test/}})
It will remove all user email starts with 'test'.
db.users.remove({"email" : { $regex : /#yopmail.com$/}})
It will remove all user email ends with 'yopmail.com'
Details are explained here, mongoDB official site