1

まず、使用しているテクノロジーは、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インデックスを使用します。「a.name」や「b.name」のように@IndexedにfieldNameを指定します。次に、「globalIndex:(a.name:foo OR b.name:foo)」のような単一のクエリですべてのフィールド名を使用します実際は、これが可能かどうかはわかりません)

  • エンティティタイプごとに個別の検索呼び出しを起動し、結果を結合します。ただし、インデックススコアに基づくページングと並べ替えを実装することは困難です。

比較的小さなデータセットを使用するため、パフォーマンスについては心配していません。

最後の質問:Cypher Luceneクエリから返される結果は、常にインデックススコアで並べ替えられていますか?そうでない場合、SDNでこれをどのように行う必要がありますか?

4

1 に答える 1

0

私はあなたの最初のオプションが最も理にかなっていると思います。

一般に、を使用indexLevel=Level.CLASSしてすべてのエンティティのグローバルインデックスを取得することもできます(またはすべてに同じインデックス名を使用します)。次に、クエリ中にタイプでフィルタリングする場合は、whereフィルターも追加しますwhere a.__type__ = {fqn}。fqnは完全修飾名です(または@TypeAliasその値を使用する場合)

現在、スコアによる並べ替えはサポートされていません。一般に、サイファーはグラフで直接アクセスできるものだけで並べ替えます。

PS 1つのフィールドに複数の@Indexedアノテーションを取り、それらすべてを尊重するアノテーションがあると便利です(ただし、フィールドからインデックスを推測する場合は問題が発生します)。SDNJIRAでお気軽に問題を提起してください

于 2012-12-06T11:51:24.217 に答える