Дважды выдать документ с другим ключом в couchdb

Скажем, у меня есть документ для сохранения с помощью couchDB, и документ выглядит так:

{
   "email": "lorem@gmail.com",
   "name": "lorem",
   "id": "lorem",
   "password": "sha1$bc5c595c$1$d0e9fa434048a5ae1dfd23ea470ef2bb83628ed6"
}

и я хочу, чтобы иметь возможность запросить документ по "id" или "по электронной почте". Поэтому при сохранении этого вида я пишу так:

db.save('_design/users', {
    byId: {
        map: function(doc) {
            if (doc.id && doc.email) {
                emit(doc.id, doc);
                emit(doc.email, doc);
            }
        }
    }
});

И тогда я мог бы запросить вот так:

db.view('users/byId', {
    key: key
}, function(err, data) {
    if (err || data.length === 0) return def.reject(new Error('not found'));
    data = data[0] || {};
    data = data.value || {};

    self.attrs = _.clone(data);
    delete self.attrs._rev;
    delete self.attrs._id;

    def.resolve(data);
});

И это работает просто отлично. Я мог бы загрузить данные либо id или же email, Но я не уверен, должен ли я это сделать.

У меня есть другое решение, которое, сохраняя один и тот же документ с двумя различными представлениями, как byId а также byEmail, но таким образом я дважды сохраняю один и тот же документ, и, очевидно, это будет занимать место в базе данных.

Не уверен, какое решение лучше.

3 ответа

Решение

Каноническим решением было бы иметь два представления, одно по электронной почте и одно по идентификатору. Чтобы не тратить место на документе, вы можете просто указать значение null, а затем использовать include_docs=true запросить параметр при запросе представления.

Кроме того, вы можете использовать _id вместо id, Таким образом, CouchDB гарантирует, что идентификатор будет уникальным, и вам не нужно будет использовать представление для зацикливания документов.

Я бы изменил на два отдельных взгляда. Это ясно и ясно. Когда вы отправляете один и тот же документ дважды в одном представлении - по идентификатору и электронной почте вы эффективно объединяете два представления в одно. Вы можете думать об этом как о дереве поиска с двумя корневыми ветвями. Я не вижу никакой причины делать это и рекомендую оставить задачу по доступу к данным и оптимизации хранилища для базы данных.

Комбинация представлений также может привести к сложным ошибкам, когда по какой-то причине вы путаете идентификатор и электронную почту.

Нет ничего плохого в том, что один и тот же документ выдается несколько раз с другим ключом. Речь идет о том, что имеет наибольшее значение для вашего приложения.

Если id а также email Всегда действительны и взаимозаменяемы способы идентификации пользователя, тогда один вид идеален. Например, когда id это своего рода уникальная ссылка на учетную запись, и пользователям разрешается использовать этот или свой (более запоминающийся) адрес электронной почты для входа в систему.

Однако, если вам необходимо различать два значения, например, id предназначен только для администраторов приложений, тогда отдельные представления, вероятно, лучше. (Вы могли бы вместо этого использовать сложный ключ... но это другой ответ.)

Другие вопросы по тегам