Таблица объединения данных веб-сервиса в Grails
Я пытаюсь выяснить лучший подход для отображения комбинированных таблиц на основе сопоставления логики и критериев поиска ввода.
Вот ситуация:
У нас есть таблица клиентов, хранящихся локально. Области интересов: ssn, имя, фамилия и дата рождения.
У нас также есть веб-сервис, который предоставляет ту же информацию. Некоторые клиенты из веб-службы такие же, как локальный файл, некоторые другие.
SSN не требуется ни в одном.
Мне нужно объединить эти данные для просмотра на дисплее Grails.
Критерии для комбинации: 1) совпадение по SSN. 2) Для всех оставшихся записей точное совпадение по имени, фамилии и дате рождения.
На данный момент нет необходимости в soundex или приблизительной логике.
Похоже, что я должен сделать, это извлечь все записи из обоих входов в одну коллекцию, каким-то образом сделать его набором для SSN. Затем уберите пустую ссн.
Это будет обрабатывать сопоставление SSN (как только я выясню, как сделать это набором).
Затем мне нужно вернуться к исходным двум исходным источникам (кэшированным в коллекции для предотвращения повторного чтения) и удалить все записи, которые существуют в наборе SSN, полученном ранее.
Затем создайте другой набор на основе имени, фамилии и даты рождения - еще раз, если я смогу выяснить, как сделать набор.
Затем объедините две производные коллекции в одну коллекцию. Коллекция должна быть отсортирована для демонстрации.
Имеет ли это смысл? Я думаю, что критерии поиска ограничат количество извлекаемых записей, поэтому я могу сделать это в памяти.
По сути, я ищу некоторые идеи о том, как код Grails будет выглядеть для достижения вышеуказанной логики (при условии, что это хороший подход). Локальная таблица клиентов - это объект домена, а то, что я получаю от WS, - это список объектов в массиве.
Кроме того, я не совсем понимаю, как будут затронуты maxresults, firstResult и порядок, используемые для отображения. Я думаю, что мне нужно прочитать во всех записях, которые в первую очередь соответствуют критериям поиска, выполнить объединение и отобразить из производной коллекции.
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
На данный момент, FilterCustomers имеет все записи, кроме тех, которые являются дубликатами по вашим двум критериям.
Другой подход состоит в том, чтобы фильтровать списки путем сортировки и выполнения операции сворачивания, комбинируя соседние элементы, если они совпадают. Таким образом, у вас есть возможность объединить данные из обоих источников.
Например:
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
}
}
}