2012-09-28 22 views
6

मैंने पुस्तकों का एक Lucene.net अनुक्रमणिका बनाई है। सभी अच्छी तरह से काम कर रहे हैं लेकिन मुझे इंडेक्स से पूछने के लिए एक और तरीका जोड़ने की जरूरत है और मैं यह नहीं समझ सकता कि इसे कैसे किया जाए।Lucene.Net 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 फ़ील्ड padding हूँ के रूप में मैंने सोचा कि यह इसके खिलाफ एक TermRangeQuery चलाने के लिए सबसे आसान होगा।

हालांकि मुझे यह देखने के लिए आयु के साथ minAge और maxAge कॉलम दोनों से पूछताछ करने की आवश्यकता है कि यह आयु minAge और maxAge द्वारा परिभाषित आयु सीमा में होती है या नहीं।

Sql होगा

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

दुर्भाग्य से मैं यह करने के लिए एक तरह से नहीं देख सकता। क्या यह लुसीन.Net में भी संभव है?

उत्तर

10

यदि स्मृति सेवा करता है तो आपको सीमा प्रश्नों का उपयोग करने में सक्षम होना चाहिए। यह प्रभावी रूप से एक मानक सीमा क्वेरी का उल्टा होता है, लेकिन आप में सक्षम होना चाहिए करने के लिए, कुछ की तरह:

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

या, किसी RangeQuery (या बेहतर अभी तक, NumericRangeQuery) के साथ या तो ऊपरी अपने निर्माण करता है, तो क्वेरी वस्तुओं या निचले बाउंड नल एक खुले अंत सीमा के रूप में काम करता है।

मैंने पहले ऊपर वाक्यविन्यास का उपयोग किया है, लेकिन समर्थन थोड़ा सा लगता है ... उस पर shaky। यदि वह काम नहीं करता, तो आप हमेशा से ही निर्धारित कर सकते हैं एक पर्याप्त रूप से कम निम्न बाउंड (0) और उच्च ऊपरी सीमा (जैसे कि, 1000), जैसे:

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

कौन सा पर्याप्त सुरक्षित होना चाहिए, किसी भी Methuselahs को छोड़कर।

+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); 

विंग

संबंधित मुद्दे