Associating a userID to user uploaded data in Meteor - mongodb

I asked this question a couple of days ago, but deleted it and I am adding more clarification here in what I'm looking at.
So what I have is a process where a user uploads a CSV and the CSV is then parsed by PapaParse and then sent server side and ultimately inserted into MongoDb.
My problem is that none of these uploads are linked to the specific user, so anyone will have access to every upload the way things look now.
What I tried to do is loop through the upload data, which looks like this;
var document = [{object}, {object}, {object}, {object}, {object}... ];
I used a for loop to loop through each of the objects and add an _id field this contains the user's id via var currentUser = this.userId;
Meteor.methods({
insert: function(document){
var currentUser = this.userId;
var newDocument = document;
for(var i = 0; i < newDocument.length; i++){
newDocument[i]._id = currentUser;
}
Bank.insert(newDocument);
}
Problem is that memory allocation is an issue for larger uploads and meteor simply crashes trying to loop through all the objects and individually adding the _id key to each object in each cell of the array.
When the document is inserted into MongoDB, it looks like this:
I know in my previous post, someone mentioned that MongoDB's insert method doesn't take an array as input, but somehow in my case, it does because the above screenshot is exactly how the document looks before being inserted into MongoDB. So basically, each object is a new document inside a MongoDB. I'm trying to find a way to bind the user's userID with each document in the databse.
Is there another way to associate the upload with the unique current user other than looping through the entire data set, which could be in the tens of thousands on some users?

Why not just do?
Meteor.methods({
insert: function(document){
var currentUser = Meteor.userId();
var newDocument = document;
Bank.insert({userId: currentUser, data: newDocument});
}
});
Now each document in your collection will have two keys: userId and data. The latter will be your array.

Related

how to use firestore wherefield method and adding document that collection to another collection

I am working a project to use shops. My structure data:
My code snippet
//current user sign in here and uid "VjZfKF1zmrV00C9VeTZxRmogybA2"
let currentUser = Auth.auth().currentUser
let db = Firestore.firestore()
db.collection("Blah").whereField("users", isEqualTo: currentUser?.uid).collection("otherPath").document().addDocument
I want to add data to use currentuser uid and if it is matching "Blah" inside documents then add that targeting document other collection.
.adddocumets or .setData it isn't allowed to firestore, so how can i figure it?
There is no way to send a query and an update statement to Firestore in one go. You will instead have to:
Execute a query to determine all documents that need to be updated.
Loop over the results of that query in your application code.
Update each document in turn inside that loop.
In addition, since users is an array field, you'll want to use the array-contains operator to match the correct documents.

Retrieving document structure based on previous records

Writing this question I'm working with .Net's LiteDB but I think the question applies to entire NoSQL matters.
One of collection in my db contains documents that don't have fixed structure. I want to let user add his own values, of whatever name and value he wants.
So, for example, document at first would have following structure:
{
"_id": 1,
"creatorId": 10
}
But user would be able to specify new value and choose whether it will be int or boolean.
{
"_id": 1,
"creatorId": 10,
"customValue": false
}
Next time user open my app, he maybe will want to use values of the same kind as he used before, so I need to show him some kind of form with inputs named based on his previous activity. So if he previously added value named "customValue", I want to show him TextView named "customValue" next time he opens page with form.
Is there a way of retrieving structure of such document based on every record from collection? Or do I need to somehow track names of added values and save them in separate collection?
In LiteDB you can use BsonDocument class to read collection documents. BsonDocument is a generic way to implement document in BSON format (with all BSON data type available).
If you use:
var col = db.GetCollection("mycol");
var doc = col.FindById(1);
foreach(var key in doc.Keys)
{
var value = doc[key];
var valueDataType = value.Type; // return an enumerable with all data types
}

Is there a way to insert a DB query directly into a new MongoDB on server side?

What I'm trying to do is take a user's query client side (via search function), send it to server via Meteor methods and if there is a search result, insert that query into another MongoDB instance? I need this in order to display search results from the user into client.
Something like this from server side:
UserSearch: function(query){
var init = Table.find({userId: this.userId}, {data: {Name: query}});
Search.insert({userId: this.userId, data: init});
},
Obviously, that doesn't work. But I'm looking for a way to allow to insert a query from one database into a new database.
So I think there are two pieces two your question here:
How do I connect to another MongoDB instance?
How do I insert data from one query result into a collection?
For #1, referencing this SO question, you can do:
var database = new MongoInternals.RemoteCollectionDriver("<mongo url>");
Search = new Mongo.Collection("search", { _driver: database });
For #2, you're simply missing the .fetch() as MasterAM pointed out:
UserSearch: function(query){
var init = Table.find({userId: this.userId, 'data.Name': query}).fetch();
Search.insert({userId: this.userId, data: init});
},
I also modified your Table query a bit as I don't think it's working in the current form. You want each field property in a query object to be in the same object. Note that the fetch will give you an array of Table objects, so you'll need to have your data field in your Search collection reflect that.

MongoDB Describe Collection

I have a user collection ,I want to see schema for this collection with data type and other detail,which I want to use in mongoosJs while making Schema.
I found a way on internet ,but it is not providing me full detail of collections-below is code for same
var users= db.users.findOne();
for (var key in users) { print (key) ; }
Is there any way to find it.
You can modify your code as per lines below:-
var col_list = db.users.findOne();
for (var col in col_list) {print (typeof col) }
There is no such thing as a schema in mongo. Documents can differ greatly from each other.
So there can be one document where field username is String and another document where field username is Integer.
You could extract the 'schema' from collection by iterating over all documents and collecting schematic information from all of them and then merging that information. But as far as I know there is no direct way in mongo itself.
Edit: a little googling landed me at variety.js, which seems to do what you need.

excecute function upon document insertion

I'm trying to find a way to achieve the following pseudo function on the server.The fields likesRecieved likesShown and likesMatch in exist in a document within the Posts collection.
I require this function to perform for every document in post collection by default. This is because Id like the function to do this...
1) find value(s) that exist in likesRecieved and likedShown fields.
2) insert these value(s) in likesMatch field.
3) remove values found in operation 1 from likesRecieved and likesShown
This is what I am essentially trying to do on the server...
likesRecieved: idA, idB, idE, idF, idL
likesShown: idE, idC, idF
..perform a function to result in the following...
likesRecieved: idA, idB, idL
likesShown: idC,
likesMatch: idE, idF
This is my code to find the ids in both arrays for one document only. The likeMatch helper returns the userIds that may exist in both 'likesRecieved' and 'likesShown' fields within a selected document in Posts collection. The resulting value(s) are then inserting into the likesMatch field.
likeMatch: function() {
var selectedPostId = Session.get('postId'); // _id of document in Post collection
var arrayOfLikeRecieved = Posts.find({_id: selectedPostId}, {fields: {LikesRecieved: 1}}).fetch();
var sumArrayRecieved = _.chain(arrayOfLikeRecieved).pluck('LikesRecieved').flatten().value();
var arrayOfLikeShown = Posts.find({_id: selectedPostId}, {fields: {LikesShown: 1}}).fetch();
var sumArrayShown = _.chain(arrayOfLikeShown).pluck('LikesShown').flatten().value();
var duplicates = _.intersection(sumArrayRecieved, sumArrayShown);
Meteor.call('insertDuplicateIntoMatchField', duplicates);
},
MongoDB doesn't have hooks like some other databases do, so there's no way to automatically have a function called when a document is inserted.
You have a couple of options, though. One way would be to have a hook in your application that runs just before inserting the document to run your function. This could be achieved in meteor by using a Collection.deny function.
If you would prefer to have the function be executed in mongodb, then you'll have to call the function manually. The problem is just how to know when the document was inserted or updated. Luckily, meteor allows you to observe changes to a cursor. You could use that to make a call out to the database and run a stored procedure (function) whenever a document gets updated.