首先,我们使用的技术是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中的fieldName,如“a.name”或“b.name”。然后使用每个字段 在单个查询中命名,如“globalIndex:(a.name: foo OR b.name: FOO )。 (实际上不确定这是否可行)
为每个实体类型启动单独的搜索调用并组合 结果。实现基于分页和排序将是困难的 但是在指数得分上。
我并不担心性能,因为我们将使用相对较小的数据集。
最后一个问题:从Cypher Lucene查询返回的结果总是按其指数得分排序吗?如果没有,我该如何在SDN中执行此操作?
答案 0 :(得分:0)
我认为你的第一个选择最有意义。
通常,您还可以使用indexLevel=Level.CLASS
获取所有实体的全局索引(或者对所有实体使用相同的索引名称)。然后在查询期间,如果要按类型过滤,还要添加where过滤器:where a.__type__ = {fqn}
fqn是完全限定名称(或者如果您使用@TypeAlias
该值)
现在不支持按分数排序,一般来说,密码只能按照您可以直接在图表中访问的内容进行排序。
P.S。虽然有一个注释在一个字段上带有多个@Indexed注释然后尊重所有这些注释会很酷(尽管如果你想从一个字段推断一个索引会引入问题)。随意在SDN JIRA
上提出问题