2012-03-22 10 views
1

私のLucene.Netインデックスには、startDateフィールドとendDateフィールドを持つドキュメントがあります。両方のフィールドには、日付がyyyyMMdd形式で格納されます。今日の日付がその2つの日付の間にある場合、ヒットを返すクエリを作成するにはどうすればよいですか?Lucene.Netを使用して2つの日付を検索します

startDateFieldValue < myTargetDate < endDateFieldValue例えば

、myTargetDateが17760604であれば、私は10660101のたstartDateフィールド値と19990101のendDateにフィールド値を持っていたバックのドキュメントを取得したいと思います。

私は、特定の建物のサイトを表すLuceneドキュメントを持つLuceneデータベースを用意しています。各サイトにはStartConstructionの日付とEndConstructionの日付があります。ユーザーが特定の日付を入力すると、その日に現在建設中のすべてのプロパティを検索したいと思います。

注:私はもっと古いバージョンのLucene.Net 1.9で作業していますが、私の会社は(まだ)アップグレードできません。

+0

例: '+ mydatefield:[10660101 TO 19990101] + myotherfield:dthrasher' –

+0

Um ...私はその質問が意味をなさないと思う。私の質問を編集して、私の言いたいことを明確にしましょう。 – dthrasher

答えて

0

RangeQueryを使用する必要があります。

RangeQuery rq = new RangeQuery(new Term("date", "10660101"),new Term("date", "19990101") ,true); 

最新のバージョンでは、パフォーマンスを向上させるためにNumericFields/NumericRangeQueryを使用することができました。

+0

これは、1つのフィールド内で日付の範囲を検索している場合に機能します。しかし、開始フィールドと終了フィールドの間にある単一の日付を検索する必要があります。 (換言すれば、あなたの例は私が必要とするものとは逆のことをしています)。 – dthrasher

+1

RangeQueryは依然として動作しますが、クエリの日付+/-何らかのステップを使用することができます。 – Mikos

1

私は自分の質問を適切に表現しているかどうかはわかりません。特定のアイテムが開始日と終了日の間にアクティブであったかどうかを調べたいと思います。 StartDateは1つのLuceneフィールドに格納され、EndDateは別のLuceneフィールドに格納されます。

は、ここで私が使用した検索スニペットです:

var searchableDate = DateTools.DateToString(dateToSearchFor, DateTools.Resolution.DAY); 

var lowerRange = new RangeQuery(null, new Term("StartDate", searchableDate), true); 
var upperRange = new RangeQuery(new Term("EndDate", searchableDate), null, true); 

var activeTodayFilter = new BooleanQuery(); 
activeTodayFilter.Add(new BooleanClause(lowerRange, BooleanClause.Occur.MUST)); 
activeTodayFilter.Add(new BooleanClause(upperRange, BooleanClause.Occur.MUST)); 
return activeTodayFilter; 

私は古いのLuceneフォーラム/ニュースグループで解決策を見つけたが、私は、リンクを覚えていないんです。

上記のクエリを書く方が簡単な場合は、教えてください。

+0

ありがとう、たくさんの落とし穴..私は最後の1週間のための同じ要件のための方法を見つけることを試みている..これは私の一日を作った:) –

3

これは、範囲クエリを使用して行うことができます。具体的には、NumericRangeQueryを使用してこれを行うことができます。これは次のようにNumericFieldを使用してあなたの日付をインデックス化し、ドキュメントに追加することから始め行うには:

var df = new NumericField(Fields.AmendedDate); 
df.SetIntValue(int.Parse(itemToIndex.startDate.ToString("yyyyMMdd"))); 
doc.Add(df); 

あなたは多くの文書see the documentationまたがってNumericFieldを再利用することで、少し速くあなたのインデックス作成を行うことができます。あなたの日付を素早く索引付けすれば、今すぐ検索する準備が整いました。このクエリは、検索など、既存のクエリに連接するために使用することができ

var q = NumericRangeQuery.NewIntRange( Fields.AmendedDate, 
             int.Parse(SearchFrom.ToString("yyyyMMdd")), 
             int.Parse(SearchTo.ToString("yyyyMMdd")), 
             true, true); 

::私たちはNumericRangeQueryを使用これを行うには、このように検索を分割

masterQuery.Add(q, BooleanClause.Occur.MUST); 

することよりもはるかに高速な命題であります数値フィールドの索引付け方法の性質上、テキスト検索を使用して検索します。また、あなたのデータ(この例では1日のレベル)を変更して、データをより広げることができます(つまり、時間、分、秒が必要な場合は、大文字から小文字までの文字列に追加します)。これの最後のポイントは、クエリを使用すると、検索のフィルタリングステップを無視することです(これは通常のクエリであり、フィルタではありません)。

+0

私は私のブログでこれをミラーリングしました - http://leapinggorilla.com/Blog/Read/3/date-range-in-lucene – Wolfwyrd

+0

数値フィールドの使用に関するヒント。それが物事をかなりスピードアップさせるかもしれないことがわかります。しかし、最後の点として、フィルタを避ける特別な理由はありますか? – dthrasher

+0

理由は、フィルタ(一般的に)がクエリよりも遅いからです。そこに素晴らしい投稿があります:http://stackoverflow.com/questions/6462350/is-filtering-faster-than-querying-in-lucene Luceneのメンテナーのコメントから、理由を説明しています。 – Wolfwyrd

関連する問題