2012-10-22 34 views
2

我在couchdb中有文档。该模式看起来象下面这样:Deduplicaton /在Couchdb中的匹配?

userId 
email 
personal_blog_url 
telephone 

我假定两个用户实际上是相同的人,只要他们有

  • 电子邮件或
  • personal_blog_url或
  • 电话

相同。

我有3次创造,基本上电子邮件/ BLOG_URL /电话映射到用户id,然后在同一项下结合的userIds成团,例如,

_view/by_email: 
---------------------------------- 
key     values  
[email protected] [123, 345] 
[email protected] [23, 45, 333] 

_view/by_blog_url: 
---------------------------------- 
key     values  
http://myblog.com [23, 45] 
http://mysite.com/ss [2, 123, 345] 

_view/by_telephone: 
---------------------------------- 
key     values  
232-932-9088   [2, 123] 
000-111-9999   [45, 1234] 
999-999-0000   [1] 

我的问题:

  • 如何将3个不同视图的结果合并到不包含重复项的最终用户表/视图中?
  • 或者是否在couchdb中执行重复数据删除是一种好的做法?
  • 或者什么是在沙发上执行重复数据删除的好方法呢?

PS。在最后的观点中,假设所有愚蠢的,我们只保留最小的userId。

谢谢。

回答

2

好问题。也许你可以听_changes并在你建议的视图中搜索你想要为真实用户所独有的字段(by_*)。

  • 合并的视图成一个(在一个地图发射不同字段):

    功能(DOC){ 如果(!!! doc.email || || doc.personal_blog_url doc.telephone)返回; emit([1,doc.email],[doc._id]); emit([2,doc.personal_blog_url],[doc._id]); emit([3,doc.telephone],[doc._id]); }

  • 合并的ID名单中减少

  • 当在变化新文件养活到达时,你可以用keys=[[1, email], [2, personal_blog_url], ...]查询视图和合并三个列表。如果其最小id小于更改的文档,请更新realId,否则使用更改的ID更新列表中的文档。

我建议使用不同的文档来存储{ userId, realId }关系。

+0

谢谢Marcin。我认为你的想法很有效。直到最后一步,我才获得成功 - 使用多个键进行搜索。如果我设置'keys = [[1,“a @ b.com”],[2,“http://a.com”],[3,“334-333-2323”]]',我总是得到所有文件都符合结果。也许我应该问一个关于这个stackoverflow的新问题? – greeness

+0

我不确定“所有文件”是什么意思。如果不使用reduce(只是map),你应该用'“rows”得到响应JSON记录:[{“id”:“1”,“key”:[1,“some @ email”],“value”:“1 “},{”id“:”2“,”key“:[1,”some @ email“],”value“:”2“},...}]'包含电子邮件,或电话号码。和你的新纪录一样。你有没有得到一些非这些领域匹配的文件?请注意,对于只是地图(没有减少)的文件将不会按用户ID排序。 –

+0

我假设'?keys = [[1,“a @ b.com”],[2,“http://a.com”],[3,“334-333-2323”]]是一个倍数键查询。我得到的结果包含一些没有这些字段匹配的文档。如果我只做单键查询,结果是正确的。多键查询有问题吗?顺便说一句,我使用的是couchDB 1.0.1。 – greeness

1

您不能只使用一个视图中创建新文档。您需要执行某种任务才能进行实际合并。

这里有一个想法。

而不是创造3次,你可以创建一个视图(即索引数据,如果它存在):

Key        Values 
---        ------ 
[userId, 'phone']    777-555-1212 
[userId, 'email']    [email protected] 
[userId, 'url']     favorite.url.example.com 

我不会别的存储除了原始值,因为你最终有很多不必要的数据重复(例如,如果您存储了完整的对象)。

然后,进行查询,你可以这样做:

...startkey=[userId]&endkey=[userId,{}] 

这会给你所有的重复信息为一系列文档为用户ID的。你仍然需要解析它,看看是否有重复。但是,这样,结果将很好地合并到单个CouchDB调用中。

Here's使用数组作为在计算器上按键的一个很好的例子。

,如果它有不是去重过程的一部分,其他的数据你会仍可能加载原来的“用户”文件。

一旦发现,你可以考虑在飞行清理数据,并防止新的重复项新的数据输入到您的应用程序中发生。

+0

谢谢。这种方法似乎适用于每个用户有重复信息的情况。但我需要的是去复制用户(w /不同的userId,但具有共同的电子邮件/网址/电话)。 – greeness