Mapreduce CouchDB(Cloudant)-为“获取唯一的结果”;以“开始”;搜索多个字段

Mapreduce CouchDB(Cloudant)-为“获取唯一的结果”;以“开始”;搜索多个字段,mapreduce,couchdb,unique,cloudant,Mapreduce,Couchdb,Unique,Cloudant,我试图从“开始于”或使用同一搜索键搜索多个字段中获得唯一的结果。 结果应该是原始文档中唯一的子节点。 等效的SQL应该类似于: 选择不同的名称、来自名称为“key%”或电子邮件为“key%”的用户的电子邮件。 我的视图功能: Map: function(doc){ if (doc.userDetails.firstName) emit([doc.userDetails.firstName.toLowerCase(), doc.userDetails],

我试图从“开始于”或使用同一搜索键搜索多个字段中获得唯一的结果。
结果应该是原始文档中唯一的子节点。
等效的SQL应该类似于:
选择不同的名称、来自名称为“key%”或电子邮件为“key%”的用户的电子邮件。


我的视图功能:

Map: function(doc){
        if (doc.userDetails.firstName) 
            emit([doc.userDetails.firstName.toLowerCase(), doc.userDetails],  null);
        if (doc.userDetails.lastName) 
            emit([doc.userDetails.lastName.toLowerCase(), doc.userDetails],  null);
    }

Reduce: function(key, values, rereduce) {
    return null;
}
问题是,如果键与每个用户文档的两个字段匹配,它将返回重复的结果。 e、 g:

JSON文档:

{
  "userDetails":{
    "email": "johnny@domain.com",
    "name":  "John Smith"
  },
  "privateFields":  { ... }
}
查询:
myView?reduce=true&group=true&startkey=[“joh”]&endkey=[“joh\ufff0”,{}]&inclusive\u end=true

上面返回重复项,一个用于匹配电子邮件字段,另一个用于匹配姓名字段。
有什么建议吗?

我建议使用一个。如何从FirstName和LastName生成名称?假设它们是串联的,您的索引将如下所示:

function(doc) {
    if(doc.userDetails.email) {
         index("email", doc.userDetails.email);
    }
    var name = doc.userDetails.firstName + " " + doc.userDetails.lastName;
    name = name.trim();
    if(name) {
         index("name", name);
    }
}
那么查询将是myIndex?q=email:joh*或name:joh*


默认情况下,值将在非字母数字字符上标记-您可能希望使用字段级分析器配置来获得适当的结果。

我认为不可能删除数据库端的重复项。谢谢!是否可以返回特定的子节点作为结果?我的意思是,直接获取“userDetails”对象,而不是请求整个文档,然后在客户端/服务器端对其进行过滤。如果userDetails很小,您可以选择对其进行索引,并使用{“store”:true}选项,以便在结果中返回它。如果它很大,那么我建议返回整个文档并在客户端进行过滤。您也可以考虑将用户名保存为一个不同的文档。不幸的是,值只能是CyrHooT中的字符串、布尔值或数字,否则文档将不会被索引。一个昂贵的解决方案是JSON.stringify()。。。