Using a different collection for users in Meteor - mongodb

I have a Meteor project which I have unfortunately been forced to modify to use PostgreSQL instead of MongoDB, through the package meteorsteam:meteor-postgres. I have managed to get everything sorta working, except the users collection, which appears to be welded together with Meteor.
Is it possible to use some other collection for it?
I have tried replacing it with an in-memory-collection Meteor.users = new Meteor.Collection(null), and hooking up some logic to sync it with a psql table. This messes up the built-in publish-functions, since the collection doesn't have a name.
There will not be a lot of users, so having the whole thing in memory as a meteorcollection is not a problem.
I have searched around the internet, but couldn't find anything even mentioning it.
Suggestions?

If you can, an easy solution is to use MongoDB just for your users table:
if (Meteor.isServer) {
var database = new MongoInternals.RemoteCollectionDriver("mongodb://127.0.0.1:27017/your_mongodb_base");
Meteor.users = new Mongo.Collection("users", { _driver: database });
}
Actually, since meteor-postgres does not use Mongo.Collection but SQL.Collection, you may even get away with just:
if (Meteor.isServer) {
Meteor.users = new Mongo.Collection("users");
}

Related

Mongodb I can see the size of the collection but, find() does not return anything

I am new to working with Mongo. I recently taken over our LearningLocker database from a previous employee. I can see using show dbs, the database has 4.188GB. But even using a simple db.learninglocker.find() is not returning anything. Any suggestions on how to review the data?
You should pass down an object as argument to the find function:
db.learninglocker.find({})

How to check if a collection has changed?

I've created a JSON API with Express.js, Mongoose and MongoDB. Currently, there's no way for the clients of the API to check if the data in a collection has changed - they would need to download the whole collection periodically.
How could I allow the clients of the API to check for changes to a collections (inserts, updates, deletions) without downloading the collection itself?
Is there a way of getting the version number of the collection, the last change timestamp or a hash of the collection with Mongoose? What is the best practice solution to this problem?
In current and earlier versions of MongoDB, you have to do it on the application side, maybe using polling.
MongoDB 3.6 has a brand new feature called change stream that allows you to listen changes happening on your collections in real time.
The sample code to listen selected changes happening on your collection is below:
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
MongoClient.connect("mongodb://172.16.0.110:27017/myproject?readConcern=majority").then(function(client){
var db = client.db('myproject')
var changeStreams = db.collection('documents').watch()
changeStreams.on('change', function(change){
console.log(change)
})
})
If you are using node.js, you need to use following node module to get it working:
"dependencies": {
"mongodb": "mongodb/node-mongodb-native#3.0.0"
}

Add an extra field to collection only on the client side and not affecting server side

Is there a way to add or inject an additional or new field to a collection and then being able to access that newly inserted field to the collection on the client side and displaying it on a template or accessing it without affecting the server side? I didn't want to compromise with the APIs or the database since it's simply a count of something, like when a customer has a total of 8 deliveries.
I was doing this code where I'm subscribing to a collection and then trying to update the collection on the client side but obviously I should have no rights on updating it:
Meteor.subscribe("all_customers", function () {
Customer.find({}).forEach(function(data) {
var delivery_count = Delivery.find({ customerID: data._id }).count();
Customer.update( { _id: data._id } , { $push: { deliveries: delivery_count } } );
});
}),
And then doing this one where I'd try to manipulate the collection by inserting new key-value pair but it won't display or nothing at all when it's sent:
Meteor.subscribe("all_customers", function () {
Customer.find({}).forEach(function(data) {
var delivery_count = Delivery.find({ customerID: data._id }).count();
data.deliveries = delivery_count;
});
}),
My main objective is to basically be able to sort the count of the deliveries in the EasySearch package without compromising with the APIs or database but the package only sorts an existing field. Or is there a way to do this with the package alone?
Forgive me if this question may sound dumb but I hope someone could help.
It's completely possible, for that you can use low level publications described here: https://docs.meteor.com/api/pubsub.html
You have 2 solutions, one standard, the other hacky:
You follow documentation, you transform your document before sending it to the client. Your server data is not affected and you can enhance data (even do joins) from your subscription. It's cool but you can't push it too far as it might collide and conflict with another publication for the same collection on the same page. Solution is well explained here: How to publish a view/transform of a collection in Meteor?
You can do a client-only collection which will be customs objects with only the data you need. You still have a server-side observer on the source collection but you'll fetch new objects that client will treat and display without any calculation. You need more code but this way, you don't mess with classic server-client collections. It's a bit overkill so ping me if you want a detailed example.

Meteor: best practice for creating database

In my Meteor application, in lib folder (the folder that all code will be executed first). I create a file name database.js which contains:
tblUser = new Mongo.collection("Users");
tblComment = new Mongo.collection("Comments");
By use this way, I think:
tblUser and tblComment is global variable, so can access like we get a table from database.
If this is first run, Users collection, Comments collection, ... will be created automatically. If not, I can get already created tblUser and tblComment document from database.
Are 2 above assumptions right ? If wrong, please correct me.
Thanks :)
Your assumptions are correct, you just gotta remember about good pub/sub code.
Although, if you still got autopublish package then yes, your Collections are something like tables that hold same data as server, you just gotta fetch() them like tblUser.find().fetch()
A meteor project have the autopublish and insecure packages. So, you should remove it and use a publish - suscribe policy in your application.
Remember, mongodb is no-sql, the collections don't will be created until you do the first insert.

Import "normal" MongoDB collections into DerbyJS 0.6

Same situation like this question, but with current DerbyJS (version 0.6):
Using imported docs from MongoDB in DerbyJS
I have a MongoDB collection with data that was not saved through my
Derby app. I want to query against that and pull it into my Derby app.
Is this still possible?
The accepted answer there links to a dead link. The newest working link would be this: https://github.com/derbyjs/racer/blob/0.3/lib/descriptor/query/README.md
Which refers to the 0.3 branch for Racer (current master version is 0.6).
What I tried
Searching the internets
The naïve way:
var query = model.query('projects-legacy', { public: true });
model.fetch(query, function() {
query.ref('_page.projects');
})
(doesn't work)
A utility was written for this purpose: https://github.com/share/igor
You may need to modify it to only run against a single collection instead of the whole database, but it essentially goes through every document in the database and modifies it with the necessary livedb metadata and creates a default operation for it as well.
In livedb every collection has a corresponding operations collection, for example profiles will have a profiles_ops collection which holds all the operations for the profiles.
You will have to convert the collection to use it with Racer/livedb because of the metadata on the document itself.
An alternative if you dont want to convert is to use traditional AJAX/REST to get the data from your mongo database and then just put it in your local model. This will not be real-time or synced to the server but it will allow you to drive your templates from data that you dont want to convert for some reason.