2016-03-28 8 views
3

私のneo4jデータベースで、姓と名に基づいてユーザーを検索する必要があります。 クエリの結果は、検索クエリにどれだけ一致するかによってソートする必要があります。 検索入力は2単語(最初/最後または最後/最初の名前)と予想されます。Neo4j - ユーザーを検索する際の適合性に基づくスコア

これまで使用していた、最初の名前を含むユーザーを検索するクエリでは、UNION ALLを使用してユーザーを再度照合しますが、姓が含まれています。 検索入力が「最初の最後」であったとします。 だから、私たちのクエリは次のとおりです。

MATCH (u:User) WHERE u.first_name =~'(?i).*first.*' RETURN u 
UNION ALL u.last_name =~'(?i).*last.*' return u 
UNION ALL u.first_name =~'(?i).*last.*' RETURN u 
UNION ALL u.last_name =~'(?i).*first.*' return u 

だから、最初の名前を持つユーザーと検索入力の姓は、クエリ結果に2回表示されます。 次に、Javaバックエンドで、各ユーザーが何回出現したかを数えます(各ユーザーには一意のユーザー名が割り当てられています)。

私はJavaのバックエンドでソートとカウントを避け、可能であれば単純に単一のクエリを使用したいと考えています。

ご協力いただければ幸いです。おかげさまで

答えて

5

テキスト形式の検索クエリでは、cypherはおそらくこれをやりたいと思う方法にはなりません。 Neo4jは実際にはApache Luceneによって実装されているレガシーインデックスをサポートしています。テキスト索引作成のためのものです。 Luceneは豊富なクエリ言語を提供して検索を改善します。

サイファールートに行くと、多くの複雑なバックエンドコードを書き上げることになりますが、あなたのマッチはややナイーブです。この例では、姓と名に文字の一致が必要であり、近いスペルミスではヒットしません。

Documentation for legacy indexing starts here。最後に、あなたが望むものだと思うので、「スコアリング」のサブページを必ず読んでください。また、extra features for lucene indexingを確認することを確認してください。これは、化合物のクエリのように、cypher経由では不可能なLuceneを使用して、よりクールなことを表示し始めるからです。

neo4jがこれを行うことができて、本当にうまく機能するということは良いニュースです。悪い知らせは、このようなものの中にはJava APIを通じてのみ利用可能なものがあり、あなたが提供する例のようにcypherから直接行うことはできないということです。

1

また、1つの正規表現にそれを組み合わせることができます。

MATCH (u:User) 
WHERE (u.first_name+" "+u.last_name) =~'(?i).*(first|last).*' RETURN u 

あなたは「名前」プロパティで一緒に両方を保存する方がよいかもしれません。 Neo4j 3.x CONTAINSもインデックスを使用しますが、現在は大文字と小文字が区別されています。

0

私が現在検索クエリで使用している基本的な一致の精度をチェックする1つの方法は、結果の文字列に対して検索キーの文字列の長さをチェックし、結果のリストを計算された差で順序付けるだけです。

MATCH (u:User) WHERE u.name ~= {searchKeyRegex} 
RETURN u.name, ABS(LENGTH(u.name) - LENGTH({searchKey})) as precision 
ORDER BY precision ASC LIMIT {limit} 

私は、これはまだpritty力ずくで認めざるを得ないが、これまでのところ、トリックを行うようです。

関連する問題