Прежде всего, мы используем технологии Neo4j, Spring и Spring Data Neo4j (все последние стабильные версии).
У нас есть требование, чтобы пользователи могли искать все наши объекты отдельно, а также обеспечивать глобальный поиск для всех объектов. Я надеюсь собрать предложения о том, как реализовать глобальный поиск. Ниже приведен некоторый (упрощенный!) код, который показывает, как я запрашиваю свои сущности. Каждая сущность использует свой собственный индекс Lucene.
Структура сущности:
@NodeEntity
public abstract class BaseEntity {
@GraphId
private Long id;
}
@NodeEntity
public class A extends BaseEntity {
private static final String INDEX = "A_Index";
public static final String SEARCH_QUERY = "START a=node:" + INDEX + "({name}) RETURN a";
@Indexed(indexType = IndexType.FULLTEXT, indexName = INDEX)
@NotBlank
private String name;
}
@NodeEntity
public class B extends BaseEntity {
private static final String INDEX = "B_Index";
public static final String SEARCH_QUERY = "START b=node:" + INDEX + "({name}) RETURN b";
@Indexed(indexType = IndexType.FULLTEXT, indexName = INDEX)
@NotBlank
private String name;
}
Классы репозитория:
@Repository
public interface ARepository extends GraphRepository<A> {
@Query(A.SEARCH_QUERY)
List<A> find(@Param("name") String name, Pageable pageable);
}
@Repository
public interface BRepository extends GraphRepository<B> {
@Query(B.SEARCH_QUERY)
List<B> find(@Param("name") String name, Pageable pageable);
}
Как я получаю доступ к классам репозитория (опять же, очень упрощенно):
@Service
public class Service {
@Autowired
private ARepository repository;
public List<A> search(final String name) {
return repository.find("name:*" + name + "*", null);
}
}
Итак, все это прекрасно работает, когда вы ищете один тип сущности. Может ли кто-нибудь предложить, как лучше всего реализовать глобальный поиск, который ищет все типы объектов?
Думает, о чем я думал:
Используйте один индекс Lucene вместо индекса для каждой сущности. Укажите имя поля в @Indexed, например «a.name» или «b.name». Затем используйте каждое имя поля в одном запросе, например "globalIndex:(a.name:foo ИЛИ b.name:foo). (на самом деле не уверен, возможно ли это)
Запустите отдельный поисковый вызов для каждого типа объекта и объедините результаты. Однако будет сложно реализовать разбиение на страницы и сортировку на основе оценки индекса.
Я не беспокоюсь о производительности, потому что мы будем использовать относительно небольшой набор данных.
Последний вопрос: всегда ли результаты, возвращаемые запросом Cypher Lucene, сортируются по индексу? Если нет, то как мне это сделать в SDN?