Как установить входную переменную в качестве ключа в JSON при создании представления в CouchBase

Я пытаюсь создать пользовательские представления на CouchBase из Node.js. Вот код, который у меня есть

app.post("/todo/:id", function(req, res){
console.log("hey" + req.body.userId)
  baseview.setDesign('design_users', {
     "$req.body.userId": {
        'map': "function (doc, meta) { if(doc.toUserName == req.body.userId) {emit(doc.status, doc.title);}}"
      }
    },
    function(err, result){
        if (err != null) console.log(err);
        else res.send(result)
    }
  ); 
})

При выполнении следующего завитка

curl -H "Content-Type: application/json" -X POST -d '{"userId": "uidam231"}' http://localhost:3000/todo/id

Хотя проектный документ design_users создается на сайте CouchBase, ожидаемое представление (uidam231) — нет. В консоли ошибок нет.

Я подозреваю, что назначение переменной req.body.userId в json, вероятно, является причиной. Обратите внимание, что имя представления ("$req.body.userId": ) и критерии фильтра (doc.toUserName == req.body.userId) нуждаются в переданной переменной.

Любые предложения, пожалуйста?


person user1384205    schedule 02.12.2016    source источник


Ответы (1)


Невозможно передать переменную в функцию карты в представлении, потому что map() и reduce() используются не для запроса данных, а для построения индекса, материализованного представления данных в ведре, а позже вы можете выполнять фильтрацию, ранжирование, сортировка, но на основе ключей, которые вы выбрали для помещения в этот индекс во время сборки (т.е. когда карта была выполнена). Проще говоря, база данных запускает вашу функцию карты один раз для всего набора данных, а затем для каждого нового/измененного документа для обновления индекса. Вот почему вы не можете передавать или использовать параметры из запроса, или это делает бессмысленным использование new Date() или Math.random() в некоторых случаях, потому что их значения будут оцениваться только один раз для каждого документа во время построения индекса, но не во время запроса.

Что вы должны сделать в вашем случае, так это построить функцию карты следующим образом:

function (doc, meta) {
  emit(doc.toUserName, [doc.status, doc.title]);
}

Это даст вам индекс просмотра, где имя пользователя является ключом, а статус и заголовок - значением. Чтобы вы могли запросить представление, используя аргумент key=, и передать туда идентификатор пользователя.

Больше информации:

  1. Запрос данных с представлениями
  2. MapReduce Views
person avsej    schedule 03.12.2016
comment
Привет @avsej: я понимаю эту часть. Чего я пытаюсь добиться, так это, скажем, при регистрации нового пользователя, я хотел бы добавить (конкретные для пользователя) представления в CouchBase. Думаю, я мог бы также запустить скрипт для добавления представлений для каждого пользователя. По сути, это не запрос. Просто представление, где функция карты проверяет определенное значение, например, число или строку. Только то, что представление вставляется (только один раз для каждого нового зарегистрированного пользователя) из Node.js - person user1384205; 05.12.2016
comment
В этом случае вы должны подставить имя пользователя как литерал в тело функции map() вместо req.body.userId, а также в имя представления. Но вы должны иметь в виду, что вы не можете обновить/добавить только один вид, вы должны каждый раз перезаписывать весь проектный документ. Может быть, N1QL решит вашу проблему? - person avsej; 05.12.2016
comment
NiQL, похоже, имеет более высокую задержку по сравнению с просмотрами. Различия, которые я планирую смягчить с помощью Couchbase lite на клиенте. Я до сих пор не могу понять преобразование в буквальную часть в приведенной выше проблеме. - person user1384205; 05.12.2016