Как сделать запрос из кода обработчика обновлений javascript
Что я пытаюсь сделать:
- Я хочу добавить данные (идентификатор, данные) в БД. При этом я хочу проверить, существует ли идентификатор, и если да, добавить к существующим данным. иначе добавьте новую запись (id, data).
Пример: это может быть БД идентификатора студента и оценки в нескольких тестах. Если идентификатор уже существует в БД, я хочу просто добавить к уже существующим результатам тестов в БД, в противном случае создать новую запись: (id, оценки)
- Для этого я настроил функцию обработчика обновлений. Я так понимаю, что вставка couchdb по умолчанию не делает выше. Теперь - как мне проверить базу данных на этот идентификатор и, если да, решить, добавлять ли новую запись или добавлять. Я знаю, что есть db.get(). Тем не менее, я полагаю, поскольку функция обработчика обновления уже является частью базы данных db, возможно, существует более эффективный способ сделать это.
Я вижу этот пример кода в вики couchdb:
function(doc, req){
if (!doc){
if ('id' in req && req['id']){
// create new document
return [req, 'New Document'];
}
// change nothing in database
return [null, 'Incorrect data format'];
}
doc[id] = req;
return [doc, 'Edited World!'];
}
несколько пояснений в этом примере, которые не ясны: откуда мы получаем идентификатор? Часто идентификатор не передается явно при добавлении в БД.
Означает ли это, что нам нужно явно передать поле с именем "_id"?
2 ответа
Как я могу проверить БД для этого идентификатора и, если да, решить, добавлять ли новую запись или добавлять.
CouchDB делает это за вас, предполагая, что HTTP-клиент запускает вашу функцию обновления с использованием идентификатора. Как описано в документации:
Когда запрос к обработчику обновлений включает идентификатор документа в URL, сервер предоставит функции самую последнюю версию этого документа
В примере кода, который вы нашли, функция обновления выглядит так: function(doc, req)
и так в коде внутри этой функции переменной doc
будет существующий документ уже "внутри" вашей базы данных CouchDB. Все входящие данные от клиента / пользователя будут найдены где-то в пределах req
,
Так что для вашего случая это может выглядеть примерно так:
function(doc, req){
if (doc) {
doc.grades.push(req.form.the_grade);
return [doc, "Added the grade to existing document"];
} else {
var newDoc = {_id:req.uuid, grades:[req.form.the_grade]};
return [newDoc, "Created new document ("+newDoc._id+") for the grade"];
}
}
Если клиент делает POST для /your_db/_design/your_ddoc/_update/your_update_function/existing_doc_id
тогда первая часть if (doc)
будет запущен, так как вы получите существующий документ (предварительно выбранный для вас) в doc
переменная. Если клиент делает POST просто /your_db/_design/your_ddoc/_update/your_update_function
тогда нет doc
при условии, и вы должны создать новый (else
пункт).
Обратите внимание, что клиенту необходимо знать идентификатор для обновления существующего документа. Либо отследите, посмотрите, либо - если нужно и поймете недостатки - сделайте их детерминированными, основываясь на чем-то известном.
В сторону: db.get()
вы упомянули, вероятно, из клиентской библиотеки CouchDB HTTP и не доступны (и не будут работать) в контексте любого обновления / шоу / список / и т.д. Функции, которые выполняются в песочнице в базе данных "себя".
Цитируется из документации:
Если вы обновляете существующий документ, у него уже должен быть установлен _id, а если вы создаете новый документ, обязательно установите для его _id что-то, сгенерированное на основе входных данных или предоставленного req.uuid. Второй элемент - это ответ, который будет отправлен обратно вызывающей стороне.
Итак, tl; dr, если _id не указан, используйте req.uuid
,
Ссылка на документацию: http://docs.couchdb.org/en/stable/ddocs/ddocs.html