son que permite mvc los internet informacion herramientas google filtros filtro filtrar cuáles como búsqueda busqueda buscador .net language-agnostic lucene.net

permite - Lucene.Net: ¿Cómo puedo agregar un filtro de fecha a mis resultados de búsqueda?



herramientas de busqueda google android (2)

Tengo mi buscador funcionando muy bien, sin embargo, tiende a devolver resultados obsoletos. Mi sitio es muy parecido a NerdDinner por el cual los eventos en el pasado se vuelven irrelevantes.

Actualmente estoy indexando así
Nota: mi ejemplo está en VB.NET, pero no me importa si los ejemplos se dan en 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

Observe cómo tengo un índice de "fecha" que almacena la fecha del evento.

Mi búsqueda se ve así

''''# 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

Probé lo siguiente, pero fue en vano (lanzó una NullReferenceException).

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

También encontré la siguiente documentación, pero no puedo encontrarle cara o cruz.
http://lucene.apache.org/java/1_4_3/api/org/apache/lucene/search/DateFilter.html


Puede combinar múltiples consultas con BooleanQuery . Como Lucene solo busca texto, tenga en cuenta que el campo de fecha de su índice debe ordenarse de la parte más significativa a la menos significativa de la fecha, es decir, en formato IS8601 ("2010-11-02T20: 49: 16.000000 + 00: 00")

Ejemplo:

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

Alternativamente, si un comodín no es lo suficientemente preciso, puede agregar un RangeQuery en RangeQuery lugar:

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


Estás enlazando a la documentación api de Lucene 1.4.3. Lucene.Net se encuentra actualmente en 2.9.2. Creo que se debe una actualización.

Primero, estás usando Store.Yes muchísimo. Los campos almacenados aumentarán su índice, lo que puede ser un problema de rendimiento. Su problema de fecha puede resolverse fácilmente almacenando las fechas como cadenas en el formato "aaaamMMddHHmmssfff" (que es realmente de alta resolución, hasta milisegundos). Es posible que desee reducir la resolución para crear menos tokens para reducir el tamaño de su índice.

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

Luego aplica un filtro a su búsqueda (el segundo parámetro, donde actualmente pasa en Nothing / null).

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

Puede hacer esto usando una BooleanQuery combinando su consulta normal con una RangeQuery, pero eso también afectaría la puntuación (que se calcula en la consulta, no en el filtro). También es posible que desee evitar modificar la consulta por simplicidad, para que sepa qué consulta se ejecuta.