CouchDB(Cloudant) - 为多个字段的“开始”搜索获得独特的结果

时间:2014-12-08 13:13:43

标签: mapreduce couchdb unique cloudant

我试图从&#34开始获得独特的结果;以"或使用相同的搜索键搜索多个字段 结果应该是原始文档中的唯一子节点 等效的SQL应该是这样的:
SELECT DISTINCT Name, Email FROM users WHERE Name LIKE 'key%' OR Email LIKE '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 doc:

{
  "userDetails":{
    "email": "johnny@domain.com",
    "name":  "John Smith"
  },
  "privateFields":  { ... }
}

查询:myView?reduce=true&group=true&startkey=["joh"]&endkey=["joh\ufff0", {}]&inclusive_end=true

以上内容返回重复项,一次用于匹配电子邮件字段,另一次用于名称字段 有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我建议使用search index。如何从FirstName和LastName生成Name?假设它们是连接的,您的索引看起来像:

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 * OR name:joh *

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