2012-05-15 9 views
6

Lucene SpanQueryを使用して、 "赤" "緑"と "青"という用語がすべて1つの文に表示されるすべての出現を見つけることはできますか?Lucene SpanQueriesを使用した文章認識検索

私の最初の(不完全/間違った)アプローチは、特別な文章マーカトークンと文の最初の部分を文の最初の単語と同じ位置に置くアナライザを作成してから、次

SpanQuery termsInSentence = new SpanNearQuery(
    SpanQuery[] { 
    new SpanTermQuery(new Term (MY_SPECIAL_SENTENCE_TOKEN)), 
    new SpanTermQuery(new Term ("red")), 
    new SpanTermQuery(new Term ("green")), 
    new SpanTermQuery(new Term ("blue")), 
    }, 
    999999999999, 
    false 
); 

SpanQuery nextSentence = new SpanTermQuery(new Term (MY_SPECIAL_SENTENCE_TOKEN)); 

SpanNotQuery notInNextSentence = new SpanNotQuery(termsInSentence,nextSentence); 

問題、当然のことながら、nextSentenceは本当にの文章ではないということです、それは文というtermsInSentence試合で1を含め、任意の文マーカーです。したがって、これは動作しません。

私の次のアプローチは、トークンを文の前に置くアナライザを作成することです(つまり、の前に、最初の単語と同じ位置ではなく最初の単語)。この問題は、MY_SPECIAL_SENTENCE_TOKENによって引き起こされた余分なオフセットを考慮する必要があることです。さらに、文章を分割するための素朴なパターン(例えば、/\.\s+[A-Z0-9]/の分割)を使用しているときは、最初は特に悪くなります。USSエンタープライズを検索すると、すべての(false)文マーカーを考慮する必要があるためです。

これはどうすればよいですか?

答えて

1

私はLucene文書として各文章を索引付けします。これには、どの原文書の元の文章かを示すフィールドが含まれます。あなたのソース資料に応じて、文/ LuceneDocのオーバーヘッドは許容されるかもしれません。

0

実際、あなたはソリューションにかなり近いようです。私は、文末のフラグをインデックス化するのはよいアプローチだと思います。問題は、文末があなたのSpanNearQueryにあることです。これがあなたを捨てています。両方とも含まれ、のスパンが見つからない場合は、にはMY_SPECIAL_SENTENCE_TOKENが含まれています。クエリはそれ自体に矛盾しているので、もちろん一致するものは見つかりません。あなたが本当に知る必要があるのは、MY_SPECIAL_SENTENCE_TOKENと重複しないスパンで3つの用語(「赤」、「緑」、「青」)が発生することです。つまり、文のトークンはそれらの間には現れません条項)。

また、Term ctors内のフィールド名の不足が問題になるだろうが、Luceneのように、ここで本当の問題ではない推測、その不満の例外をスローする必要があります。これが書かれた時点でのLuceneのバージョンは、SpanNearsの不一致のフィールドについて不平を言っていない可能性があるので、おそらく言及する価値があります。

これは私には仕事に表示されます。

SpanQuery termsInSentence = new SpanNearQuery(
    new SpanQuery[] { 
     new SpanTermQuery(new Term ("text", "red")), 
     new SpanTermQuery(new Term ("text", "green")), 
     new SpanTermQuery(new Term ("text", "blue")), 
    }, 
    9999, 
    false 
); 

SpanQuery nextSentence = new SpanTermQuery(new Term ("text", MY_SPECIAL_SENTENCE_TOKEN)); 

SpanQuery notInNextSentence = new SpanNotQuery(termsInSentence,nextSentence); 

限り文章を分割する場所として、代わりに単純な正規表現のアプローチを使用しての、私はjava.text.Breakiteratorを使用しようとするだろう。それは完璧ではありませんが、それはかなり良い仕事をします。

関連する問題