2010-12-30 19 views
7

Araştırmacımın gerçekten iyi çalıştığını biliyorum, ancak eski olan sonuçları döndürme eğiliminde. Sitem NerdDinner'a çok benziyor, geçmişte yaşanan olaylar ilgisiz hale geliyor.Lucene.Net: Arama sonuçlarıma nasıl bir tarih filtresi ekleyebilirim?

Şu anda bu
nota gibi indeksleme ediyorum: örnekler C#

Public Function AddIndex(ByVal searchableEvent As [Event]) As Boolean Implements ILuceneService.AddIndex 

     Dim writer As New IndexWriter(luceneDirectory, New StandardAnalyzer(), False) 

     Dim doc As Document = New Document 

     doc.Add(New Field("id", searchableEvent.ID, Field.Store.YES, Field.Index.UN_TOKENIZED)) 
     doc.Add(New Field("fullText", FullTextBuilder(searchableEvent), Field.Store.YES, Field.Index.TOKENIZED)) 
     doc.Add(New Field("user", If(searchableEvent.User.UserName = Nothing, 
            "User" & searchableEvent.User.ID, 
            searchableEvent.User.UserName), 
           Field.Store.YES, 
           Field.Index.TOKENIZED)) 
     doc.Add(New Field("title", searchableEvent.Title, Field.Store.YES, Field.Index.TOKENIZED)) 
     doc.Add(New Field("location", searchableEvent.Location.Name, Field.Store.YES, Field.Index.TOKENIZED)) 
     doc.Add(New Field("date", searchableEvent.EventDate, Field.Store.YES, Field.Index.UN_TOKENIZED)) 

     writer.AddDocument(doc) 

     writer.Optimize() 
     writer.Close() 
     Return True 

    End Function 

Bildirimi verilirse benim örnek VB.NET içinde, ama umurumda değil benim ne bir " olay tarihini depolayan tarih.

Arama sonra aşağıdakileri deneyin yaptım bu

''# code omitted 
     Dim reader As IndexReader = IndexReader.Open(luceneDirectory) 
     Dim searcher As IndexSearcher = New IndexSearcher(reader) 
     Dim parser As QueryParser = New QueryParser("fullText", New StandardAnalyzer()) 
     Dim query As Query = parser.Parse(q.ToLower) 

     ''# We're using 10,000 as the maximum number of results to return 
     ''# because I have a feeling that we'll never reach that full amount 
     ''# anyways. And if we do, who in their right mind is going to page 
     ''# through all of the results? 
     Dim topDocs As TopDocs = searcher.Search(query, Nothing, 10000) 
     Dim doc As Document = Nothing 

     ''# loop through the topDocs and grab the appropriate 10 results based 
     ''# on the submitted page number 
     While i <= last AndAlso i < topDocs.totalHits 
       doc = searcher.Doc(topDocs.scoreDocs(i).doc) 
       IDList.Add(doc.[Get]("id")) 
       i += 1 
     End While 
''# code omitted 

gibi görünüyor, ama (bir NullReferenceException attı) boşuna oldu.

 While i <= last AndAlso i < topDocs.totalHits 
      If Date.Parse(doc.[Get]("date")) >= Date.Today Then 
       doc = searcher.Doc(topDocs.scoreDocs(i).doc) 
       IDList.Add(doc.[Get]("id")) 
       i += 1 
      End If 
     End While 

şunlarla belgelerine buldum ama bir BooleanQuery ile birden fazla sorgu birleştirebilirsiniz o
http://lucene.apache.org/java/1_4_3/api/org/apache/lucene/search/DateFilter.html

+0

Tamam, mvc'i geri eklediğinizi sanıyordum. Yani bir IronPython veya IronRuby örneğiyle tamam mı? ;) – jfar

+0

: -p [uh bunu prolly ediyor] –

cevap

9

. Lucene.Net şu anda 2.9.2 seviyesindedir. Bir yükseltme yapılması gerektiğini düşünüyorum.

İlk önce Store.Yes birimini kullanıyorsunuz. Depolanan alanlar, dizininizi daha büyük bir performans sorununa dönüştürebilir. Tarih probleminiz, "yyyyMMddHHmmssfff" biçimindeki dizeleri tarih olarak depolayarak kolayca çözülebilir (bu gerçekten çok yüksek çözünürlük, milisaniye kadardır). Endeks boyutunu azaltmak için daha az jeton oluşturmak için çözünürlüğü azaltmak isteyebilirsiniz.

var dateValue = DateTools.DateToString(searchableEvent.EventDate, DateTools.Resolution.MILLISECOND); 
doc.Add(new Field("date", dateValue, Field.Store.YES, Field.Index.NOT_ANALYZED)); 

Sonra (şu anda hiçbir şey/boş geçmek ikinci parametre,), aramanız için bir filtre uygulamak.

var dateValue = DateTools.DateToString(DateTime.Now, DateTools.Resolution.MILLISECOND); 
var filter = FieldCacheRangeFilter.NewStringRange("date", 
       lowerVal: dateValue, includeLower: true, 
       upperVal: null, includeUpper: false); 
var topDocs = searcher.Search(query, filter, 10000); 

Bunun bir RangeQuery ile normal sorgu birleştiren bir BooleanQuery kullanarak yapabilirsiniz, ama bu aynı zamanda (sorgu değil filtre üzerinde hesaplanan) puanlama etkileyeceğini. Ayrıca, basitlik için sorguyu değiştirmekten kaçınmak isteyebilirsiniz, böylece hangi sorgunun yürütüldüğünü bilirsiniz.

+0

örnek, bir Google araması yaparken bulduğum şeydi. Lucene.Net v2.4.0.2 kullanıyorum –

+0

Kullanıcının “date: dd/mm/yyyy” ile arama yapmasını istiyorum. –

+0

Sihirli Changes.txt dosyasında hızlı arama 2.4 olduğunu gösteriyor.0 2008-10-06 yayınlandı ve hata düzeltmeleri ve yeni özellikler uzun bir listede 1100 satırından sonra. Sanırım yeni bir dizin formatı var (otomatik olarak yükseltileceksiniz, ancak eski sürümler okunmaya devam edemez), ancak yine de bir yükseltme düşünmelisiniz. – sisve

7

ait yazı-tura yapamazlar. Lucene sadece metin notu arandığından, indeksinizdeki tarih alanının en önemlisi tarihin en az önemli kısmına, yani IS8601 biçimine ("2010-11-02T20: 49: 16.000000 + 00: 00") göre sıralanması gerekir.

Örnek: bir joker yeterince kesin olmadığı

Lucene.Net.Index.Term searchTerm = new Lucene.Net.Index.Term("fullText", searchTerms); 
Lucene.Net.Index.Term dateRange = new Lucene.Net.Index.Term("date", "2010*"); 

Lucene.Net.Search.Query termQuery = new Lucene.Net.Search.TermQuery(searchTerm); 
Lucene.Net.Search.Query dateRangeQuery = new Lucene.Net.Search.WildcardQuery(dateRange); 

Lucene.Net.Search.BooleanQuery query = new Lucene.Net.Search.BooleanQuery(); 
query.Add(termQuery, BooleanClause.Occur.MUST); 
query.Add(dateRangeQuery, BooleanClause.Occur.MUST); 

Alternatif eğer ekleyebilirsiniz RangeQuery yerine: sen Lucene 1.4.3 aPI belgelerine bağlıyoruz

Lucene.Net.Search.Query termQuery = new Lucene.Net.Search.TermQuery(searchTerm); 
Lucene.Net.Index.Term date1 = new Lucene.Net.Index.Term("date", "2010-11-02*"); 
Lucene.Net.Index.Term date2 = new Lucene.Net.Index.Term("date", "2010-11-03*"); 
Lucene.Net.Search.Query dateRangeQuery = new Lucene.Net.Search.RangeQuery(date1, date2, true); 

Lucene.Net.Search.BooleanQuery query = new Lucene.Net.Search.BooleanQuery(); 
query.Add(termQuery, BooleanClause.Occur.MUST); 
query.Add(dateRangeQuery, BooleanClause.Occur.MUST); 
+0

oh, nasıl bir boolean araması yapılacağını bulmalıyım ;-) –

İlgili konular