Описание проблемы
Я реализую алгоритм анализа ссылок в огромной графовой базе данных.
База данных графа состоит из сущностей (вершин) и отношений (ребер).
У каждого типа сущности есть свойства. Например, Человек: [возраст, рост, вес].
Каждая связь также имеет свойства: например, Звонок(Телефон,Телефон) : [дата, продолжительность] или Собственное(Человек, Телефон) : [дата начала, дата окончания].
Теперь мне дан шаблон со следующей структурой:
[тип-сущности,ограничения] [тип-отношения,ограничения] [тип-сущности,ограничения] [тип-отношения,ограничения] ... [тип-сущности,ограничения]
Например:
[человек,возраст>20] [собственный, дата начала>1/01/2010] [телефон, заканчивается на "5"] [дата звонка>1/1/2010] [телефон, начинается на "6" ] [владелец, дата начала‹02.01.2011] [человек, рост>40].
Мне нужно найти ВСЕ допустимые назначения для всех сущностей и отношений в шаблоне.
Я могу запросить базу данных, используя следующие примитивы:
- Найдите первые 1000 назначений [entity-type,relationship-type,entity-type] для заданного набора ограничений.
- Найдите следующие 1000 для вышеуказанного
- Найдите первые назначения [concrete-entity,relationship-type,entity-type] для заданного набора ограничений.
- Найдите следующие 1000 для вышеуказанного
Сохранение всех ответов на заданный запрос в оперативной памяти невозможно. Каждой тройке сущность-связь-сущность могут быть миллионы (миллиарды?) назначений. Однако предполагается, что количество назначений для всего шаблона невелико.
Что я пробовал:
Для цепочки ET1-RT1-ET2-RT2-ET3-RT3... Наивной реализацией будет:
Get first 1000 (ET1-RT1-ET2)
for each concrete ET2:
Get first 1000 (ET2-RT2-ET3)
for each concrete ET3:
...
Проблема в том, что я могу решать одни и те же подзадачи более одного раза.
Я ищу алгоритм, который устраняет такую избыточность, а также эффективно использует память.
Примечание:
Я ищу алгоритм. Не для ответа типа "Использовать SQL JOIN"/"Использовать SPARQL"...