2011-01-14 9 views
3

Lucene.Netを使って検索機能を実装しました。この指数には、「Aレベル」を含む英国の学術資格が含まれています。Lucene.Net - スペース区切りのフレーズを単一のトークンとして扱うには?

「A Level」というフレーズで検索することができますが、標準アナライザーを使用すると「A」はストップワードとして取り除かれ、「レベル」のみがインデックス/検索されます。

これを回避するにはどうすればよいですか?私はどうにかして "Aレベル"を "Aレベル"にトークン化したり、カスタムアナライザを作成したりする必要があると推測しています。

これが最善のアプローチですか?

編集:私は、全体の検索フレーズクエリにしたくないたく

注意。つまり、私の検索ボックスで、ユーザに< "A Level" AND English Maths Physics>を入力させ、 "A Level"と英語の数学または物理のいずれかを返すようにします。これを反映するように質問が更新されました。私は特にアパートレベル "から、すべてのケースでストップワードとして「A」の使用を維持したいと思い

フレーズ「レベル」は、それ自身の特定の分野ではないが、それは中ですフレーズを含む可能性のあるフリーテキストフィールド。

答えて

3

使用PhraseQuery - ブール建設により、他と組み合わせることができる

EDITED

あなたは、フレーズ全体を検索する必要はありません。あなたはどのアナライザを使用している? - あなたはそれはあなたがコンテンツをインデックス付けましたか

BooleanQuery rootQuery = new ... 
PhraseQuery q1 = new PhraseQuery("A Level"); 
TermQuery q2 = new TermQuery("English"); 
TermQuery q3 = new TermQuery("Maths"); 
TermQuery q4 = new TermQuery("Physics"); 
rootQuery.Add(q1, BooleanClause.Occur.SHOULD); //or MUST - depends on you 
rootQuery.Add(q2, BooleanClause.Occur.SHOULD); 
rootQuery.Add(q3, BooleanClause.Occur.SHOULD); 
rootQuery.Add(q4, BooleanClause.Occur.SHOULD); 
+0

しかし、私は全体の検索フレーズクエリになりたくないしたいです。すなわち、私の検索ボックスで、ユーザがを入力できるようにして、これは" A Level "と英語の数学または物理のいずれかを返します。これを反映するように質問が更新されました。 –

+2

@Dewfy - それでも問題は解決しないのですか?すなわち「Aレベル」の「A」は標準アナライザによってストップワードとして取り除かれ、フレーズクエリは「Aレベル」ではなく「レベル」のすべてのインスタンスを返すことになる。 –

1

(私は今それをテストすることはできませんので、申し訳ありませんが、それは、擬似コードである)は、次のように見えるの試料について

Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29, new Hashtable()); 

だから、インデックス上位アナライザでcontenxt:あなたは、あなたがコンストラクタでストップワードを指定することができStandardAnalyzerを使用している場合(あなたは空のリストを使用することができます)。その後、あなたはQueryParser(上記アナライザを使用してください)か、手動でクエリを作成することができますを使用してコンテンツを照会することができます

 // Phrase query 
     PhraseQuery phraseQuery = new PhraseQuery(); 
     phraseQuery.Add(new Term("MyField", "A")); 
     phraseQuery.Add(new Term("MyField", "Level")); 

     // Or query 
     BooleanQuery orQuery = new BooleanQuery(); 
     orQuery.Add(new BooleanClause(new TermQuery(new Term("MyField", "English")), BooleanClause.Occur.SHOULD)); 
     orQuery.Add(new BooleanClause(new TermQuery(new Term("MyField", "Maths")), BooleanClause.Occur.SHOULD)); 
     orQuery.Add(new BooleanClause(new TermQuery(new Term("MyField", "Physics")), BooleanClause.Occur.SHOULD)); 

     // Main query 
     BooleanQuery query = new BooleanQuery(); 
     query.Add(phraseQuery, BooleanClause.Occur.MUST); 
     query.Add(orQuery, BooleanClause.Occur.MUST); 

さようなら

+0

私はStandardAnalyzerを使用しています。私は具体的にはすべてのケースで「Aレベル」からのストップワードとして「A」を使用したいと思っています。これを明確にするために質問を更新します。 –

+0

なぜですか?次に、2つのアナライザ(停止語として「A」、停止語ではないもの)を作成し、ビジネスのニーズに応じて(索引付けおよび検索中に)アナライザ間で選択します。 PerFieldAnalyzerWrapperを使用してフィールドごとにアナライザーを設定することもできます。または、結局のところ、別のアナライザーを選択してください... – rrejc

+0

私は彼がフィールドに基づいてではなく、フィールドの用語に基づいてストップワードを切り替えたいと思う。だから、 'PerFieldAnalyzerWrapper'は動作しません。 – Xodarap

1

KeywordAnalyzerはStandardAnalyzerとは異なり、文字列をトークン化しません。私はこれのネット実装があると仮定しています - possibly this

私はしばしばこのような何かを(Javaは、以下の、注意してください)やる:私は「句」かどうかなどのテキストを処理するために天気をを決定するために、フィールド名を使用することにより、

private ReusableAnalyzer getReusableAnalyzer(String fieldName, Reader reader) { 
    boolean phrase = treatAsPhrase(fieldName); 
    ReusableAnalyzer ra = new ReusableAnalyzer(); 
    TokenStream result = phrase ? new KeywordTokenizer(reader) : new StandardTokenizer(version, reader); 

+0

他のテキストも含まれているので、フィールドをトークン化します。 「A Level」というフレーズは、それ自身の特定のフィールドではなく、フレーズを含めることができるフリーテキストフィールドにあります。私はこれを明確にするために質問を更新しました。 –

+0

StopFilterのカスタム実装を作成して、オリジナルをコピーすることができます。この場合、ストップワード 'A'にマッチしてから次のトークンにルックアヘッドすると、 'Level'の場合はストップを適用しないでください。 – Joel

2

私はこれが現在Luceneで実行可能ではないと思います。私はこれを行う半完成のプラグを持っています、あなたはそれを見ることができますhere。位置とオフセットの属性は設定されていません。つまり、フレーズの検索は正しく機能しませんが、うまくいけば頭がおかしくなります。

+0

これは私が心に留めていたものと非常によく似ています。私はそれを試してみて、ポジションを取得して属性のオフセットを試してみましょう。 –

+0

@Gareth D:それを働かせたら、コードを投稿して盗むことができます:-) – Xodarap

+0

カスタムStopFilterを作成するだけではどうですか? – Joel

1

これは、少しカスタマイズしてLuceneで実行できます。

1)ストップワードが保存されている別のフィールドを作成します。 StandardAnalyzerを継承する独自のアナライザーを作成する必要がありますが、ベースコンストラクターには停止語を指定しません。

public class PreserveStopWordsAnalyzer : StandardAnalyzer 
{ 
    public PreserveStopWordsAnalyzer() : base(Version.LUCENE_29, new Hashtable()) 
    {} 
} 

2)「停止単語」フィールドに対して引用語を検索します。たとえば

+RegularField:English +StopWordField:"A Level"

関連する問題