Update single field in CouchDB - couchdb

I want update one field in a document. I created a new document:
And I would like to change the value of field name from aaa to test. I copied a script from: wiki.apache.org/couchdb/Document_Update_Handlers, and I created a new design document:
Next I created a URL:
localhost:5984/asd/_design/temp/_update/in-place-query/8d6257096bbb199a3757954c00000d0c?name=title&value=test
That should update my field. I instead saw the error:
"{"error":"TypeError","reason":"{[{<<\"message\">>,<<\"point is undefined\">>},\n {<<\"fileName\">>,<<\"../share/couchdb/server/main.js\">>},\n {<<\"lineNumber\">>,1500},\n {<<\"stack\">>,\n <<\"(\\\"_design/temp\\\",[object Array],[object Array])#../share/couchdb/server/main.js:1500\\n()#../share/couchdb/server/main.js:1562\\n#../share/couchdb/server/main.js:1573\\n\">>}]}"}"
Have you got any idea to repair it?

Your update handler design doc should be in the form:
{
"_id": "_design/app",
"updates": {
"accumulate": "function (doc, req) { // Your code here }"
}
}
For further information, please checkout this SO post.
Let me know if this helps !

Related

mongoose.watch() fields' name changing by itself

I begin with mongoose and I have to use watch() method on a collection.
When i want to catch insert, there are no problems.
Nevertheless, when I want to retrieve the changes of an update, I don't know why, in some cases, mongoose changes the name of my fields?
registration.watch(). on('change', data => {
if(data.operationType == "update") {
console.log(data.updateDescription.updatedFields);
}
)};
my registration's collection is made up of persons who can accept or decline an invitation, and a person can change they answer. So it's basically a removal of the person from one array of data to be put in the other one.
The only problem I have is my array's name sometimes "change" :
{
__v: 100,
accepted: [
{
_id: 5faa76d048dd6e0017e631d4,
user: 5faa752848dd6e0017e631d2
},
{
_id: 5faa9ab06048a20017774610,
user: 5fa8fabc60260ec31606d71e
},
],
'declined.1': { _id: 5faf037a141f030017863484, user: 5faa74de48dd6e0017e631d0 },
for example here, my field declined change to "declined.1", why it's happening ? and how to avoid this ? or at least, how can i get declined's array in this situation ?
When you update a document in MongoDB, it only writes the deltas to the operations log, which is what the watch function pulls from.
The dot notation declined.1 means index 1 of the declined array. The change document you provided would be expected from pushing a new object onto the declined array. Essentially, it is saving space by not repeating all of the array elements that didn't change.
If you need to retrieve the entire document, you could set the fullDocument to updateLookup. See http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#watch

How to improve the performance of query in mongodb?

I have a collection in MongoDB with more than 5 million documents. Whenever I create a document inside the same collection I have to check if there exists any document with same title and if it exists then I don't have to add this to the database.
Example: here is my MongoDB document:
{
"_id":ObjectId("3a434sa3242424sdsdw"),
"title":"Lost in space",
"desc":"this is description"
}
Now whenever a new document is being created in the collection, I want to check if the same title already exists in any of the documents and if it does not exists, then only I want to add it to the database.
Currently, I am using findOne query and checking for the title, if it not available only then it is added to the database. I am facing the performance issue in this. It is taking too much time to do this process. Please suggest a better approach.
async function addToDB(data){
let result= await db.collection('testCol').findOne({title:data.title});
if(result==null){
await db.collection('testCol').insertOne(data);
}else{
console.log("already exists in db");
}
}
You can reduce the network round trip time which is currently 2X. Because you execute two queries. One for find then one for update. You can combine them into one query as below.
db.collection.update(
<query>,
{ $setOnInsert: { <field1>: <value1>, ... } },
{ upsert: true }
)
It will not update if already exists.
db.test.update(
{"key1":"1"},
{ $setOnInsert: { "key":"2"} },
{ upsert: true }
)
It looks for document with key1 is 1. If it finds, it skips. If not, it inserts using the data provided in the object of setOnInsert.

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.

Node Mongoose: Update many query with reference to current record

I want to update one column of all rows collection by creating a concatnated string
My Schema has a property fileName and I would like construct a new property url.
Can I refernce the current row/record to build a query which would look something like this?
dbSchema.File.update({}, { $set: { url: '/view/images/'+ fileName}}, options, callback);
Obviously the above does not work because fileName is not in scope..
Whats the best way of achieving this?
You'll need to do this manually and update each document in JavaScript and resave the document.
db.file.find().forEach(function(doc) {
// make your needed updates
db.file.update({_id:doc._id}, { $set : { url: 'newPath/' + filename }});
});
While you could do it from Mongoose, there's not much reason to if you have access to the console.
Otherwise, you'll need to do the exchange on the fly as you encounter unchanged documents, by looking for an indicator that the data hasn't been fixed.

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.

Resources