MongoDB nested arrays aggregated update array - node.js

I need to create a website that on a user click the like button he toggle the like, so if he liked the post the like is removed and if the post doesn't have the like user will like it.
Data structure of database is like this:
{
"_id":"5f9d838caf0d921703818c89",
"page": "nickname",
"posts":[
{
"post": postData,
"likes": ["user1","user3"]
}
]
}
I need a nodejs function to add or remove user name from likes.
Example:
user2 click the like button
the function to give or remove likes know the post index in "posts" so for example index post 0
function check if posts.0.likes contains the like of "user2"
if "user2" is not included in array then include it else remove from array

Related

Using Design Documents to add an element to a list

Users can press a button on my website to declare interest in a course. For every course there is a document in my CouchDB installation. These documents look like this:
{
"_id": "...",
"_rev": "...",
"name": "...",
"description": "...",
"userList": []
}
When a users presses the button his name should be added to "userList". I wrote a Design Document for this:
{
"_id": "_design/updateList",
"_rev": "...",
"updates": {
"addUser": "function(doc, req) {doc['userList'] = req['name']; var message = 'user added'; return [doc, message];}",
}
}
I know that this cannot be the right solution because the list can never be longer than one user name like this. However, not even that works. When I press on the button, the line ""userList": []" disappears from the corresponding document.
What's the problem here? I use PHP-On-Couch to run the Design Document but there shouldn't be any problems in my PHP code. I see in the CouchDB log that CouchDB receives the user name just fine.
The direct problem is that a req object does not have a field called "name" so:
doc['userList'] = req['name']
is equivalent to:
doc['userList'] = undefined
you may have meant to use userCtx req.userCtx.name directly if users are logged in, or req.query.name if you have added it as a parameter.
More generally, you probably meant to push their name on to the array which is probably fine if class sign up isn't very high volume. An alternate approach is to generate an independent document for each user+class and rely on views to count them.

Update mongoDB with todolist information?

I have a todolist feature in my frontend, here is a demo: https://gyazo.com/a10fcd7c470439fe5cc703eef75b437f
It is all updated using an array in a Vue component and then using v-models to keep track of the data and change the UI to reflect that array.
When the user clicks 'send' i want it to send off the data to the database.
The issue im having is that i can't work out how to import newly created 'todos'(the text box and check box that is created when the + button is clicked) into the database.
This is what each todolist document looks like in my 'todolists' collection in the mongo:
{
"_id":"5caca1498accb128c8974d56",
"title":"todolist1 11111 11111 11111 11111",
"userEmail":"test#gmail.com",
"todos":[
{
"_id":"5caca1498accb128c8974d57",
"description":"Get this done",
"completed":true}
],
"dateDue":"2019-04-07T18:24:31.207Z",
"__v":0
}
The 'save' button in the demo has a v-on:click attribute that has a function named saveTodoList(), which then makes an axios post request to the route /updateTodoList
Feel free to ask any questions that will help you answer my question :)
When a new todo is saved after clicking plus button, make a request on /updateTodoList with parent document's _id. So your request might look something like this:
POST /updateTodoList:
Body:
{ "_id": "5caca1498accb128c8974d56",
"todo": {
"description": "This is a newly added todo description",
"completed": false
}
}
Then, on the server side, parse this body object and update the document with matching _id and push the new todo into the document. Your query will look something like this:
todolist.findOneAndUpdate({_id: req.body._id}, { $push: {todos: req.body.todo } })
Hope this helps.
Edit:
Each time you push a todo using above query, mongo inserts that element to the todos array. For pushing multiple todos in single query, use $each operator along with $push. Official documentation here.

Add and Remove Within Mongoose

{
"_id" : 1,
"_name" : "peter",
"favourites" : [
{
"user_id" : 1
},
{
"user_id" : 2
}
]
}
I have this schema within Mongo, and I'm using Node/Express/Mongoose to manage my stack. I'm new to this particular stack and I have a 'favourite' button on the website I'm building. What's the best way to add/remove from favourites?
Do I really need to setup two routes, one for POST and another for PUT? I'm not sure what the best way is to solve this particular problem, I've done some searching and I've not found anything that relevant.
I'm not going to give you the full answer as it's always good to learn, so I've give you 90% of what I think is what you're looking for. Do a check for the name and if it doesn't exist within the favourites array, do the following:
db.collection.update(
{ "username": "walterwhite" },
{ $push:
{
favourites: [ { "user_id": "7" } ]
}
}
)
First of all you will need routes for any of the actions. It's probably the best practice to use the HTTP Verbs (GET/POST/PUT/DELETE etc.). Then your routes would look something like this: (this could be wrapped in a file that contains all routes and later required in the main app file (ex. app.js).)
module.exports = function (router) {
router.route('/favourites')
.get(function (req, res, next) {
// Code for getting all items
})
.post(function (req, res, next) {
// Code for inserting new item
})
.delete(function (req, res, next) {
// Code for deleting an item
});
}
Then you will need to build a form with fields corresponding to the item's properties and use POST as a submit method. You will need it for inserting (adding) new items. The request sent from the form, will send you to the post route, where you will handle your logic for appending item to the list.
To implement the deletion you will have to send a DELETE, request passing an identifier of the item you'd want to delete. You will handle this code in the delete route.
Of course, the get route is for getting all items in the collection for further processing or visualizing.
you must create an object id associated to every user_id. you can create such id's using.you can associate multiple models with mongoose population
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
"favourites" : [
{
"_id" : ObjectId("57338c9cc5c8cf74181b4cff"),
"user_id" : 1
},
{
"_id" : ObjectId("5734588e5a54d45434693a09")
"user_id" : 2
}
]
either render the page or send a json object as response with the object id in it as per your setup.
user_id-2
user_id-1
now you can make an ajax request with the object id when clicked on a particular <a> tag.you can achieve this with jquery. Then remove the user associated with that id from your favorites.
If you add more details.I can give you a specific answer.

Saving a Person or Group field using REST

Does anyone know how to save a Person field using REST?
I have tried the following and it works:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonFieldId" : 1
}
But this only works if you know the ID. I don't have that! How can I get it? I have the key which is i.0#w|domain\userName.
I tried the following and it doesnt work either:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonField" : { "__metadata": { "type": "SP.Data.UserInfoItem" }, "Name": "i.0#w|domain\userName" }
}
Any ideas?? Thanks!
I haven't done this with a Person field, but I did do something similar with a managed metadata field. I basically had to pass in additional information as an object to create the value in the field.
See if passing in the ID of the user along with the name works. I'm about to try this myself as I have the same need.
{
"MyPersonField": { "Name": "i.0#w|domain\userName", "ID": 1 }
}
EDIT: Ok, updating this field is easier than I thought. I was able to perform the update by simply passing in the ID of the user to the Id field:
{
"MyPersonFieldId": 1
}
This means the user should already be in the site collection, so if the user doesn't exist the request will fail.
Use the below code to get Current User ID to save user under People and group column. People column name is Requestor. But to save user we have to specify column name as RequestorId
var userid = _spPageContextInfo.userId; // To get current user ID
var itemProperties={'Title':vTitle,'RequestorId':userid};
The thing is that User information is a lookup field thereby MyPersonField does not exist on your SharePoint list if you use an OData endpoint, I really don't know how to save data but same problem happened to me when I tried to read a user.
for example {server}/{api}/list/getbytitle('mylist')/items does not return MyPersonField instead return MyPersonFieldId.
But if we use:
{server}/{api}/list/getbytitle('mylist')/items/?$select=*,MyPersonField/Name&$expand=MyPersonField
We are able to work with MyPersonField lookup values.

Automatic document updates in couchdb

I have 10,000+ couchdb documents, each having (simplified) format like -
{
"First Name" : "John",
"Last Name" : "Doe"
}
I want to add another field to this document, which is e-mail, so that document now looks like -
{
"First Name" : "John",
"Last Name" : "Doe",
"e-mail" : ""
}
I understand that I can easily update this document by inserting a new JSON, in new format.
But my question is how can I add new field automatically to "all 10,000+" docs that I have existing in the DB? Do I need to write my own script to read each doc and update each one of them individually? Or is there a simpler way?
If you use views to access your data, you can modify the view without having to modify the documents. Just emit an email value with a default of "".
Assuming the above is no good, use a view to show you which documents need upgrading.
function(doc) {
// views.email_upgrade.map
if(! ('e-mail' in doc)) {
var key = [doc["Last Name"], doc["First Name"]];
emit(key, {_id:doc._id, _rev:doc._rev});
}
Query /db/_design/foo/_view/email_upgrade?include_docs=true. You can add a &limit=N property to help. Query. The doc value in each row is a document that needs to upgrade. You can send them back with POST /db/_bulk_docs. Loop until you have 0 rows. Once you have 0 rows, add a check to your validate_doc_update function.

Resources