2

Say I have a doc to save with couchDB and the doc looks like this:

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

and I want to be able to query the doc either by 'id' or 'email'. So when save this as a view I write so:

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

And then I could query like this:

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);
});

And it works just fine. I could load the data either by id or email. But I'm not sure if I should do so.

I have another solution which by saving the same doc with two different view like byId and byEmail, but in this way I save the same doc twice and obviously it will cost space of the database.

Not sure which solution is better.

4

3 回答 3

5

规范的解决方案是有两个视图,一个通过电子邮件,一个通过 id。为了不浪费文档空间,您可以只发出 null 作为值,然后在include_docs=true查询视图时使用查询参数。

此外,您可能想要使用_id而不是id. 这样,CouchDB 可以确保 ID 是唯一的,并且您不必使用视图来循环文档。

于 2013-07-01T09:24:38.083 回答
1

使用不同的密钥多次发出同一个文档绝对没有错。这是关于什么对您的应用程序最有意义。

如果id并且email始终是识别用户的有效且可互换的方式,那么单一视图是完美的。例如,什么时候id有某种独特的帐户参考,并且允许用户使用该帐户或他们的(更容易记住的)电子邮件地址登录。

但是,如果您需要区分这两个值,例如id仅适用于应用程序管理员,那么单独的视图可能会更好。(您可能可以改用复杂的密钥......但这是另一个答案。)

于 2013-07-01T10:15:08.480 回答
1

我将更改为两个单独的视图。这是明确和明确的。当您在一个视图中两次发出相同的文档时——通过一个 id 和电子邮件,您实际上将这两个视图合并为一个。您可以将其视为具有 2 个根分支的搜索树。我认为没有任何理由这样做,并建议将数据访问和存储优化工作留给数据库。

当由于某种原因混淆了 id 和电子邮件时,视图组合也可能会产生棘手的错误。

于 2013-07-01T07:11:23.240 回答