2016-03-30 6 views
0

Beim Versuch, datetime (long) numerische Felder zu sortieren, erhalte ich immer eine FormatException.Lucene - Sortierdatum als NumericField

When converting a string to DateTime, parse the string to take the date before putting each variable into the DateTime object.

Hinzufügen des Zahlenfeld:

doc.Add(new NumericField("creationDate", Field.Store.YES, true) 
    .SetLongValue(DateTime.UtcNow.Ticks); 

Add Sortierung:

// boolean query  
var sortField = new SortField("creationDate", SortField.LONG, true); 
var inverseSort = new Sort(sortField); 
var results = searcher.Search(query, null, 100, inverseSort); // exception thrown here 

den Index Inspizieren, kann ich überprüfen, ob 'creation' Feld "long" Werte speichert. Was könnte diese Ausnahme verursachen?

EDIT:

Abfrage

var query = new BooleanQuery(); 
foreach (var termQuery in incomingProps.Select(p => new TermQuery(new Term(kvp.Key, kvp.Value.ToLowerInvariant())) 
{ 
    query.Add(new BooleanClause(termQuery , Occur.Must)); 
} 

return query; 

Version: Lucene.Net 3.0.3

UPDATE:

Dieses Problem wieder auftritt, nun mit INT-Werten. Ich habe Lucene.Net-Quellcode heruntergeladen und das Problem behoben.

Es ist irgendwo im FieldCache, wenn Sie versuchen, den Wert "\ \ \ \ \ \ \" zu Integer zu analysieren, was ein bisschen seltsam erscheint.

FieldCacheException

Ich füge diese Werte als numerische Felder:

doc.Add(new NumericField(VersionNum, int.MaxValue, Field.Store.YES, 
true).SetIntValue(VersionValue)); 

Ich bekomme die Ausnahme, wenn ich soll mindestens 1 Hit zurück zu bekommen. Nach dem Index Inspektion ich sehe, dass der Begriff des Feldes, wie folgend:

Version Term

Und das Feld Text:

enter image description here

EDIT:

Ich habe ein fest einprogrammiert int-Wert und fügte einige Segmente hinzu:

doc.Add(new Field(VersionNum, NumericUtils.IntToPrefixCoded(1), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 

Welche führte das Versionsfeld wie auf der Speicherung: enter image description here

Und noch, wenn ich versuche ich die Parsing-Fehler erhalten zu sortieren:

var sortVersion = new SortField(VersionNum, SortField.INT, true); 

Für jede Ausnahme, Lucene versucht "zu analysieren \ b \ 0 \ 0 \ 0 ". Betrachtet man den vorangestellten Code als String gespeichert, würde 1 in "\ b \ 0 \ 0 \ 0 \ 1" übersetzt werden.

Wird Lucene im FieldCache wahrscheinlich etwas Müll hinterlassen?

+0

können Sie zeigen, wie "Abfrage" erstellt wird? – AndyPook

+0

@AndyPook Nur die Frage bearbeitet und die "Abfrage" hinzugefügt. Es funktioniert gut, wenn ich nach DOC sortiere. –

+0

Das Datumsfeld ist nicht in der Abfrage enthalten, es wird nur zum Sortieren verwendet. Nehmen wir an, dass ich nur nach einer benutzerdefinierten Feld-ID frage, die gewährt wird, um eine Reihe von Ergebnissen zurückzugeben. –

Antwort

1

Hier ist ein Komponententest, der versucht zu erfassen, was Sie fragen. Der Test besteht. Können Sie erklären, was der Unterschied zu Ihrem Code ist?(Einen vollständigen fehlgeschlagenen Test zu veröffentlichen würde uns helfen zu verstehen, was Sie tun :-))

using System; 
using System.Linq; 
using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

using Lucene.Net.Search; 
using Lucene.Net.Index; 
using Lucene.Net.Analysis.Standard; 
using Lucene.Net.QueryParsers; 
using Lucene.Net.Documents; 
using Lucene.Net.Store; 

namespace SO_answers 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
     [TestMethod] 
     public void TestShopping() 
     { 
      var item = new Dictionary<string, string> 
      { 
       {"field1", "value1" }, 
       {"field2", "value2" }, 
       {"field3", "value3" } 
      }; 

      var writer = CreateIndex(); 
      Add(writer, item); 
      writer.Flush(true, true, true); 

      var searcher = new IndexSearcher(writer.GetReader()); 
      var result = Search(searcher, item); 

      Assert.AreEqual(1, result.Count); 

      writer.Dispose(); 
     } 

     private List<string> Search(IndexSearcher searcher, Dictionary<string, string> values) 
     { 
      var query = new BooleanQuery(); 
      foreach (var termQuery in values.Select(kvp => new TermQuery(new Term(kvp.Key, kvp.Value.ToLowerInvariant())))) 
       query.Add(new BooleanClause(termQuery, Occur.MUST)); 

      return Search(searcher, query); 
     } 

     private List<string> Search(IndexSearcher searcher, Query query) 
     { 
      var sortField = new SortField("creationDate", SortField.LONG, true); 
      var inverseSort = new Sort(sortField); 
      var results = searcher.Search(query, null, 100, inverseSort); // exception thrown here 


      var result = new List<string>(); 
      var matches = results.ScoreDocs; 
      foreach (var item in matches) 
      { 
       var id = item.Doc; 
       var doc = searcher.Doc(id); 
       result.Add(doc.GetField("creationDate").StringValue); 
      } 
      return result; 
     } 

     IndexWriter CreateIndex() 
     { 
      var directory = new RAMDirectory(); 

      var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30); 
      var writer = new IndexWriter(directory, analyzer, new IndexWriter.MaxFieldLength(1000)); 

      return writer; 
     } 
     void Add(IndexWriter writer, IDictionary<string, string> values) 
     { 
      var document = new Document(); 
      foreach (var kvp in values) 
       document.Add(new Field(kvp.Key, kvp.Value.ToLowerInvariant(), Field.Store.YES, Field.Index.ANALYZED)); 
      document.Add(new NumericField("creationDate", Field.Store.YES, true).SetLongValue(DateTime.UtcNow.Ticks)); 

      writer.AddDocument(document); 
     } 
    } 
} 
+0

Danke für die Antwort, du warst immer eine große Hilfe. Trotzdem hatte ich in diesem Fall ein "vergessenes" Dokument unter Tausenden mit einem falschen Datumswert. Ich werde deine Antwort als akzeptiert markieren. Danke –

+0

Aloha andy, ich habe Ihre Antwort als akzeptiert markiert. Das Problem tritt zufällig auf und ich habe keine Ahnung von dem, was vor sich geht. Allerdings habe ich einige neue Erkenntnisse, die zur Ursache führen könnten. –

+0

hast du das Problem entdeckt? – AndyPook