0

我试图找出基于匹配逻辑和输入搜索条件显示组合表的最佳方法。

情况如下:

我们有一个本地存储的客户表。感兴趣的字段是 ssn、名字、姓氏和出生日期。

我们还有一个提供相同信息的网络服务。来自 web 服务的客户有的与本地文件相同,有的不同。

两者都不需要 SSN。

我需要组合这些数据以在 Grails 显示器上查看。

组合的标准是 1) 在 SSN 上匹配。2) 对于任何剩余的记录,名字、姓氏和出生日期完全匹配。

此时不需要 soundex 或近似逻辑。

看起来我应该做的是将两个输入中的所有记录提取到一个集合中,以某种方式使其成为 SSN 上的一个集合。然后删除空白ssn。

这将处理 SSN 匹配(一旦我弄清楚如何制作它)。

然后,我需要返回原始的两个输入源(缓存在集合中以防止重新读取)并删除之前派生的 SSN 集中存在的任何记录。

然后,根据名字、姓氏和出生日期创建另一组——如果我能弄清楚如何制作一组的话。

然后将两个派生集合组合成一个集合。出于展示目的,应对集合进行分类。

这有意义吗?我认为搜索条件将限制提取的记录数量,因此我可以在内存中执行此操作。

本质上,我正在寻找一些关于 Grails 代码如何实现上述逻辑的想法(假设这是一个好方法)。本地客户表是一个域对象,而我从 WS 得到的是一个对象数组列表。

此外,我并不完全清楚用于显示的 maxresults、firstResult 和 order 将如何受到影响。我想我需要先读入所有符合搜索条件的记录,进行组合,然后从派生集合中显示。

4

1 回答 1

1

执行此操作的传统 Java 方法是将本地和远程对象都复制到具有自定义比较器的 TreeSet 容器中,首先用于 SSN,其次用于名称/出生日期。

这可能看起来像:

def localCustomers = Customer.list()
def remoteCustomers = RemoteService.get()
TreeSet ssnFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.ssn <=> c2.ssn}))
ssnFilter.addAll(localCustomers)
ssnFilter.addAll(remoteCustomers)
TreeSet nameDobFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.firstName + c1.lastName + c1.dob <=> c2.firstName + c2.lastName + c2.dob}))
nameDobFilter.addAll(ssnFilter)
def filteredCustomers = nameDobFilter as List

此时,filteredCustomers 具有所有记录,除了那些根据您的两个条件重复的记录。

另一种方法是通过排序和折叠操作来过滤列表,如果它们匹配,则组合相邻的元素。这样,您就有机会合并来自两个来源的数据。

例如:

def combineByNameAndDob(customers) {
    customers.sort() { 
        c1, c2 -> (c1.firstName + c1.lastName + c1.dob) <=> 
                  (c2.firstName + c2.lastName + c2.dob)
    }.inject([]) { cs, c -> 
        if (cs && c.equalsByNameAndDob(cs[-1])) {
            cs[-1].combine(c)  //combine the attributes of both records
            cs
        } else {
            cs << c
        }
    }
}
于 2010-03-03T17:54:06.200 回答