2012-09-28 5 views
6

私はLucene.netの書籍の索引を作成しました。すべてうまくいっていますが、インデックスを照会する別の方法を追加する必要があり、それを実行する方法がわかりません。Lucene.NetはTermRangeQueryより大きい/小さいですか?

基本的に各書籍の年齢は適切です。これは、 - minAgeとmaxAgeの2つの列で表されます。どちらの列も整数です。

あなたは、私はそれはそれに対してTermRangeQueryを実行するのが最も簡単だろうと思って、私はMINAGEとMAXAGEフィールドを水増ししています見ることができるように私は、次のループ

foreach (var catalogueBook in books) 
{ 
    var book = new Book(catalogueBook.CatalogueBookNo,catalogueBook.IssueId); 

    var strTitle = book.FullTitle ?? ""; 
    var strAuthor = book.Author ?? ""; 
    // create a Lucene document for this book 
    var doc = new Document(); 

    // add the ID as stored but not indexed field, not used to query on 
    doc.Add(
     new Field(
      "BookId", 
      book.CatalogueBookNo.ToString(System.Globalization.CultureInfo.InvariantCulture), 
      Field.Store.YES, 
      Field.Index.NOT_ANALYZED_NO_NORMS, 
      Field.TermVector.NO)); 

    // add the title and author as stored and tokenized fields, the analyzer processes the content 
    doc.Add(
     new Field("FullTitle", 
      strTitle.Trim().ToLower(), 
      Field.Store.YES, 
      Field.Index.ANALYZED, 
      Field.TermVector.NO)); 

    doc.Add(
     new Field("Author", 
      strAuthor.Trim().ToLower(), 
      Field.Store.YES, 
      Field.Index.ANALYZED, 
      Field.TermVector.NO)); 

    doc.Add(
     new Field("IssueId", 
      book.IssueId, 
      Field.Store.YES, 
      Field.Index.NOT_ANALYZED_NO_NORMS, 
      Field.TermVector.NO)); 

    doc.Add(
     new Field(
      "PublicationId", 
      book.PublicationId.Trim().ToLower(), 
      Field.Store.YES, 
      Field.Index.NOT_ANALYZED_NO_NORMS, 
      Field.TermVector.NO)); 

    doc.Add(
     new Field(
      "MinAge", 
      book.MinAge.ToString("0000"), 
      Field.Store.YES, 
      Field.Index.NOT_ANALYZED_NO_NORMS, 
      Field.TermVector.NO)); 

    doc.Add(
     new Field(
      "MaxAge", 
      book.MaxAge.ToString("0000"), 
      Field.Store.YES, 
      Field.Index.NOT_ANALYZED_NO_NORMS, 
      Field.TermVector.NO)); 

    doc.Add(new NumericField("Price",Field.Store.YES,true).SetDoubleValue(Convert.ToDouble(book.Price))); 

    //Now we can loop through categories 
    foreach(var bc in book.GetBookCategories()) 
    { 
     doc.Add(
      new Field("CategoryId", 
       bc.CategoryId.Trim().ToLower(), 
       Field.Store.YES, 
       Field.Index.NOT_ANALYZED_NO_NORMS, 
       Field.TermVector.NO)); 
    } 

    // add the document to the index 
    indexWriter.AddDocument(doc); 
} 

// make lucene fast 
indexWriter.Optimize(); 
} 

でこれらのフィールドをインデックス化して保存しています。

しかし、minAgeとmaxAgeで定義されたAgeの範囲にAgeが含まれるかどうかを調べるには、AgeでminAge列とmaxAge列の両方を照会する必要があります。

SQLは、残念ながら、私はこれを行う方法を参照することはできません

Select * 
From books 
where @age >= minAge and @age <= maxAge 

だろう。これはLucene.Netでも可能ですか?

答えて

10

メモリが使用されている場合は、範囲クエリを使用してこれを行うことができます。上部のいずれかで

+minAge:[* TO @age] +maxAge:[@age TO *] 

それとも、あなたは、クエリオブジェクトを構築する場合、RangeQuery(まだまたはより良い、NumericRangeQuery):これは、効果的に、標準的な範囲クエリの逆ですが、あなたのことができるようになり、のようなものまたは下限のヌルは、オープンエンドの範囲として機能します。

私は上記の構文を使用しましたが、サポートはちょっと...不安定です。問題が解決しない場合、あなたは常にだけ設定することができます十分に低い下限(0)と高い上限(たとえば、1000)、のような:任意のMethuselahsがなければ、十分に安全でなければなりません

+minAge:[0000 TO @age] +maxAge:[@age TO 1000] 

+0

はあなたのアドバイスを使用し、それが御馳走を働きました。検索のためのソリューションで終わったので、私は以下で概要を説明します。 – wingyip

4

上記のfemtoRgonの回答の助けを借りて、この作業を終了しました。マーベラス

var q = new TermRangeQuery("MinAge", "0000",searchTerms.Age.ToString("0000"), true, true); 
mainQuery.Add(q, BooleanClause.Occur.MUST); 
q = new TermRangeQuery("MaxAge", searchTerms.Age.ToString("0000"),"9999", true, true); 
mainQuery.Add(q, BooleanClause.Occur.MUST); 

ウィング

関連する問題