I am using MongoDB with Codeigniter (Cimongo) and I need to print out the results from
the command db.currentOp on a webpage so that I can use the data to debug.
How can I do this?
Thankful for all help!
Based on Viewing and Terminating Current Operation from the MongoDB docs, the db.currentOp() command is simply a query against the special $cmd.sys.inprog collection of a database. You can also confirm this via the JS shell:
$ mongo
MongoDB shell version: 2.1.0
connecting to: test
> db.currentOp
function (arg) {
var q = {};
if (arg) {
if (typeof arg == "object") {
Object.extend(q, arg);
} else if (arg) {
q.$all = true;
}
}
return this.$cmd.sys.inprog.findOne(q);
}
I haven't worked with CodeIgniter or Cimongo, but looking at Cimongo.php, you should be able to use the get() method with $cmd.sys.inprog to receive a cursor, which you can then use to read the first element. There doesn't appear to be any abstraction for MongoCollection::findOne(), but that would have been my first choice for doing this in raw PHP:
$mongo = new Mongo();
$inprog = $mongo->selectCollection('test', '$cmd.sys.inprog');
var_dump($inprog->findOne());
Related
I am trying to execute the random java scripts which work from mongo command line but I am trying to execute using mongo .net core c# driver I didn't find the eval function in new API, so I created the extension method like this....but it is not working as expected
public static async Task<BsonValue> EvalAsync(this IMongoDatabase database, string javascript)
{
var client = database.Client as MongoClient;
if (client == null)
throw new ArgumentException("Client is not a MongoClient");
var function = new BsonJavaScript(javascript);
var op = new EvalOperation(database.DatabaseNamespace, function, null);
using (var writeBinding = new WritableServerBinding(client.Cluster, new CoreSessionHandle(NoCoreSession.Instance)))
{
try
{
return await op.ExecuteAsync(writeBinding, CancellationToken.None);
}catch(Exception ex)
{
return await Task.FromResult<string>(ex.InnerException.StackTrace);
}
}
}
test script:
db.collection.updateOne(
{"PageId":NumberInt(12)},
{$set:
{
"PageName":"testpage",
"Section":[{
"SectionId":NumberInt(1),
"Title":"testpage",
"Contents":""}],
"Message":[{
"MessageId":NumberInt(1),
"MessageTypeId":NumberInt(2),
"MessageText":"teswt message."
}]
}
},
{upsert: true}
);
printjson(db.runCommand({getLastError:1}));
I am trying to execute the random java scripts which work from mongo command line but I am trying to execute using mongo .net core c# driver I didn't find the eval function in new API, so I created the extension method like this....but it is not working as expected
Has somebody found a way to check if an index has been created after calling _ensureIndex / createIndex without using the Mongo Shell but in Meteor server code?
I am writing a package test, where I want to assert, that the indices have been created during some package code execution.
I'm using this code to extend collection prototype for getting indexes synchronously:
getIndexes.js:
const Future = Npm.require('fibers/future');
Mongo.Collection.prototype.getIndexes = function() {
const raw = this.rawCollection();
const future = new Future();
raw.indexes(function(err, res) {
if(err) {
future.throw(err);
}
future.return(indexes);
});
return future.wait();
};
I'm discovering moteor.js, and I struggle with the basics. So far I just followed the tutorial, and everything is fine until I get to the Collections part. My app is running, mongod is running, but for some reason, the app crashes on this line
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to hannibal.";
};
Template.hello.events({
'click input' : function () {
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
});
}
When I open the page in localhost:3000, I get this message
ReferenceError: Mongo is not defined
at app/hannibal.js:1:28
Any idea why is it doing this ? I thought it might come from the fact that I'm using meteor for Windows.
In >v0.9.1, if you're using Mongo in a custom package, check that package.js includes api.use('mongo', [client, server]) inside onUse. See this related question.
It sounds like you have an old version of Meteor installed.
Run meteor update from the command line.
What worked for me was directly importing Mongo from Meteor as so:
import { Mongo } from 'meteor/mongo'
I'm very keen to utilize Meteor as the framework for my next project. However, there is a requirement to keep customer data separated into different MongoDB instances for users from different customers.
I have read on this thread that it could be as simple as using this:
var d = new MongoInternals.RemoteCollectionDriver("<mongo url>");
C = new Mongo.Collection("<collection name>", { _driver: d });
However, I was dished this error on my server/server.js. I'm using meteor 0.9.2.2
with meteor-platform 1.1.0.
Exception from sub Ep9DL57K7F2H2hTBz Error: A method named '/documents/insert' is already defined
at packages/ddp/livedata_server.js:1439
at Function._.each._.forEach (packages/underscore/underscore.js:113)
at _.extend.methods (packages/ddp/livedata_server.js:1437)
at Mongo.Collection._defineMutationMethods (packages/mongo/collection.js:888)
at new Mongo.Collection (packages/mongo/collection.js:208)
at Function.Documents.getCollectionByMongoUrl (app/server/models/documents.js:9:30)
at null._handler (app/server/server.js:12:20)
at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1594)
at _.extend._runHandler (packages/ddp/livedata_server.js:943)
at packages/ddp/livedata_server.js:737
Can anyone be so kind as to enlighten me whether or not I have made a mistake somewhere?
Thanks.
Br,
Ethan
Edit: This is my server.js
Meteor.publish('userDocuments', function () {
// Get company data store's mongo URL here. Simulate by matching domain of user's email.
var user = Meteor.users.findOne({ _id: this.userId });
if (!user || !user.emails) return;
var email = user.emails[0].address;
var mongoUrl = (email.indexOf('#gmail.com') >= 0) ?
'mongodb://localhost:3001/company-a-db' :
'mongodb://localhost:3001/company-b-db';
// Return documents
return Documents.getCollectionByMongoUrl(mongoUrl).find();
});
and this is the server side model.js
Documents = function () { };
var documentCollections = { };
Documents.getCollectionByMongoUrl = function (url) {
if (!(url in documentCollections)) {
var driver = new MongoInternals.RemoteCollectionDriver(url);
documentCollections[url] = new Meteor.Collection("documents", { _driver: driver });
}
return documentCollections[url];
};
Observation: The first attempt to new a Meteor.Collection works fine. I can continue to use that collection multiple times. But when I log out and login as another user from another company (in this example by using an email that is not from #gmail.com), the error above is thrown.
Downloaded meteor's source codes and peeked into mongo package. There is a way to hack around having to declare different collection names on the mongodb server based on Hubert's suggestion.
In the server side model.js, I've made these adaptation:
Documents.getCollectionByMongoUrl = function (userId, url) {
if (!(userId in documentCollections)) {
var driver = new MongoInternals.RemoteCollectionDriver(url);
documentCollections[userId] = new Meteor.Collection("documents" + userId, { _driver: driver });
documentCollections[userId]._connection = driver.open("documents", documentCollections[userId]._connection);
}
return documentCollections[userId];
};
Super hack job here. Be careful when using this!!!!
I believe Meteor distinguish its collections internally by the name you pass to them as the first argument, so when you create the "documents" collection the second time, it tries to override the structure. Hence the error when trying to create the /documents/insert method the second time.
To work around this, you could apply a suffix to your collection name. So instead of:
new Meteor.Collection('documents', { _driver: driver });
you should try:
new Meteor.Collection('documents_' + userId, { _driver: driver })
I am trying to send a request parameter through to an 'exports' method for a mongodb find in an express.js, backbone.js application. I am having a difficult
time getting the parameters to pass through to mongodb and with '#'.
The breakage is the passing of parameters into the exported mongodb function.
Here is the flow of data:
First the request is successfully routed to the 'upcoming' function:
"upcoming/uni/:uni" : "upcoming",
It flows on to the 'upcoming' function without a problem.
upcoming: function(uni) {
console.log("uni: "+uni);
pag.reset();
console.log("Hit upcoming list target");
setCollectionType('upcoming');
var upcomingCourses = buildCollection();
// ------------------------------------------------------------------------
// here is the problem how do I pass the parameter value through the fetch?
// Although it may also have to do with '#' please read on.
// ------------------------------------------------------------------------
upcomingCourses.fetch({success: function(){
$("#content").html(new ListView({model: upcomingCourses, page: 1}).el);
}});
this.headerView.selectMenuItem('home-menu');
},
The routing for the mongo methods is:
app.get('/upcoming/uni/:uni', mongomod.findUpcoming);
So the following method is exported from the mongodb js file and is executed reliable. However the req.params are not passed through.
Interspersed in the code I have described its' runtime behaviour:
exports.findUpcoming = function(req, res) {
console.log("university", req.params.uni); // This consistently is unpopulated
var uni = req.params.uni;
console.log("Size: "+req.params.length); // This will always be 0
for (var i=0; i < req.params.length; i++) {
console.log("Parameters: "+req.params[i]);
}
db.collection('upcoming', function(err, collection) {
if (typeof uni === 'undefined') {
console.log("The value is undefined");
uni = "Princeton University"; // here we add a string to test it it will work.
}
collection.find({university:uni}).toArray(function(err, items) {
if (err) {
console.log("Error: "+err);
} else {
console.log("No Error");
console.log("Count: "+items.length);
console.log(items[0]['university']);
res.send(items);
}
});
});
};
On additional and important note:
The url, in a working, runtime environment would be:
http://localhost:3000/#upcoming/uni/Exploratorium
This one fails, but the following URL will work in passing the params through these functions however it returns the JSON to the screen rather then
the rendered version:
http://localhost:3000/upcoming/uni/Exploratorium
The problem could be a miss understanding of # and templates. Please, if you see the error enlightenment would be greatly appreciated.
Nothing after the # gets passed to the server. See How to get hash in a server side language? or https://stackoverflow.com/a/318581/711902.
I found a solution to the problem of passing the parameters from the client side to the server side. By changing the url of the collection the parameters will be passed to the server side:
upcomingCourses.url = "/upcoming/uni/"+uni; // <-- here's the ticket where uni is param
upcomingCourses.fetch({success: function(){
$("#content").html(new ListView({model: upcomingCourses, page: 1}).el);
}});
This can be made more elegant but it is a way to pass the parameters on to the server.
Thanks