You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by dn...@apache.org on 2007/11/26 19:45:40 UTC
svn commit: r598376 - in /lucene/java/trunk: ./
src/java/org/apache/lucene/search/ src/test/org/apache/lucene/search/
Author: dnaber
Date: Mon Nov 26 10:45:39 2007
New Revision: 598376
URL: http://svn.apache.org/viewvc?rev=598376&view=rev
Log:
LUCENE-1045: make SortField.AUTO work with long
Added:
lucene/java/trunk/src/test/org/apache/lucene/search/TestDateSort.java
Modified:
lucene/java/trunk/CHANGES.txt
lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java
lucene/java/trunk/src/java/org/apache/lucene/search/FieldSortedHitQueue.java
lucene/java/trunk/src/java/org/apache/lucene/search/Sort.java
Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=598376&r1=598375&r2=598376&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Mon Nov 26 10:45:39 2007
@@ -23,6 +23,11 @@
(Mike McCandless)
+ 2. LUCENE-1045: SortField.AUTO didn't work with long. When detecting
+ the field type for sorting automatically, numbers used to be
+ interpreted as int, then as float, if parsing the number as an int
+ failed. Now the detection checks for int, then for long,
+ then for float. (Daniel Naber)
API Changes
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java?rev=598376&r1=598375&r2=598376&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java Mon Nov 26 10:45:39 2007
@@ -21,6 +21,7 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.search.ExtendedFieldCache.LongParser;
import java.io.IOException;
import java.util.Locale;
@@ -149,6 +150,12 @@
}
};
+ private static final LongParser LONG_PARSER = new LongParser() {
+ public long parseLong(String value) {
+ return Long.parseLong(value);
+ }
+ };
+
private static final FloatParser FLOAT_PARSER = new FloatParser() {
public float parseFloat(String value) {
return Float.parseFloat(value);
@@ -273,6 +280,45 @@
};
// inherit javadocs
+ public long[] getLongs (IndexReader reader, String field) throws IOException {
+ return getLongs(reader, field, LONG_PARSER);
+ }
+
+ // inherit javadocs
+ public long[] getLongs(IndexReader reader, String field, LongParser parser)
+ throws IOException {
+ return (long[]) longsCache.get(reader, new Entry(field, parser));
+ }
+
+ Cache longsCache = new Cache() {
+
+ protected Object createValue(IndexReader reader, Object entryKey)
+ throws IOException {
+ Entry entry = (Entry) entryKey;
+ String field = entry.field;
+ LongParser parser = (LongParser) entry.custom;
+ final long[] retArray = new long[reader.maxDoc()];
+ TermDocs termDocs = reader.termDocs();
+ TermEnum termEnum = reader.terms (new Term (field, ""));
+ try {
+ do {
+ Term term = termEnum.term();
+ if (term==null || term.field() != field) break;
+ long termval = parser.parseLong(term.text());
+ termDocs.seek (termEnum);
+ while (termDocs.next()) {
+ retArray[termDocs.doc()] = termval;
+ }
+ } while (termEnum.next());
+ } finally {
+ termDocs.close();
+ termEnum.close();
+ }
+ return retArray;
+ }
+ };
+
+ // inherit javadocs
public float[] getFloats (IndexReader reader, String field)
throws IOException {
return getFloats(reader, field, FLOAT_PARSER);
@@ -455,10 +501,15 @@
ret = getInts (reader, field);
} catch (NumberFormatException nfe1) {
try {
- Float.parseFloat (termtext);
- ret = getFloats (reader, field);
+ Long.parseLong(termtext);
+ ret = getLongs (reader, field);
} catch (NumberFormatException nfe2) {
- ret = getStringIndex (reader, field);
+ try {
+ Float.parseFloat (termtext);
+ ret = getFloats (reader, field);
+ } catch (NumberFormatException nfe3) {
+ ret = getStringIndex (reader, field);
+ }
}
}
} else {
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FieldSortedHitQueue.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FieldSortedHitQueue.java?rev=598376&r1=598375&r2=598376&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FieldSortedHitQueue.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FieldSortedHitQueue.java Mon Nov 26 10:45:39 2007
@@ -409,6 +409,8 @@
return comparatorString (reader, field);
} else if (lookupArray instanceof int[]) {
return comparatorInt (reader, field);
+ } else if (lookupArray instanceof long[]) {
+ return comparatorLong (reader, field);
} else if (lookupArray instanceof float[]) {
return comparatorFloat (reader, field);
} else if (lookupArray instanceof String[]) {
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/Sort.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Sort.java?rev=598376&r1=598375&r2=598376&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/Sort.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/Sort.java Mon Nov 26 10:45:39 2007
@@ -30,24 +30,30 @@
* and does not need to be stored (unless you happen to want it back with the
* rest of your document data). In other words:
*
- * <p><code>document.add (new Fieldable ("byNumber", Integer.toString(x), Fieldable.Store.NO, Fieldable.Index.UN_TOKENIZED));</code></p>
+ * <p><code>document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.UN_TOKENIZED));</code></p>
*
*
* <p><h3>Valid Types of Values</h3>
*
- * <p>There are three possible kinds of term values which may be put into
- * sorting fields: Integers, Floats, or Strings. Unless
+ * <p>There are four possible kinds of term values which may be put into
+ * sorting fields: Integers, Longs, Floats, or Strings. Unless
* {@link SortField SortField} objects are specified, the type of value
* in the field is determined by parsing the first term in the field.
*
* <p>Integer term values should contain only digits and an optional
- * preceeding negative sign. Values must be base 10 and in the range
+ * preceding negative sign. Values must be base 10 and in the range
* <code>Integer.MIN_VALUE</code> and <code>Integer.MAX_VALUE</code> inclusive.
* Documents which should appear first in the sort
* should have low value integers, later documents high values
* (i.e. the documents should be numbered <code>1..n</code> where
* <code>1</code> is the first and <code>n</code> the last).
*
+ * <p>Long term values should contain only digits and an optional
+ * preceding negative sign. Values must be base 10 and in the range
+ * <code>Long.MIN_VALUE</code> and <code>Long.MAX_VALUE</code> inclusive.
+ * Documents which should appear first in the sort
+ * should have low value integers, later documents high values.
+ *
* <p>Float term values should conform to values accepted by
* {@link Float Float.valueOf(String)} (except that <code>NaN</code>
* and <code>Infinity</code> are not supported).
Added: lucene/java/trunk/src/test/org/apache/lucene/search/TestDateSort.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/TestDateSort.java?rev=598376&view=auto
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/search/TestDateSort.java (added)
+++ lucene/java/trunk/src/test/org/apache/lucene/search/TestDateSort.java Mon Nov 26 10:45:39 2007
@@ -0,0 +1,118 @@
+package org.apache.lucene.search;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.analysis.WhitespaceAnalyzer;
+import org.apache.lucene.document.DateTools;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+
+/**
+ * Test date sorting, i.e. auto-sorting of fields with type "long".
+ * See http://issues.apache.org/jira/browse/LUCENE-1045
+ */
+public class TestDateSort extends TestCase {
+
+ private static final String TEXT_FIELD = "text";
+ private static final String DATE_TIME_FIELD = "dateTime";
+
+ private static Directory directory;
+
+ public void setUp() throws Exception {
+ // Create an index writer.
+ directory = new RAMDirectory();
+ IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true);
+
+ // oldest doc:
+ // Add the first document. text = "Document 1" dateTime = Oct 10 03:25:22 EDT 2007
+ writer.addDocument(createDocument("Document 1", 1192001122000L));
+ // Add the second document. text = "Document 2" dateTime = Oct 10 03:25:26 EDT 2007
+ writer.addDocument(createDocument("Document 2", 1192001126000L));
+ // Add the third document. text = "Document 3" dateTime = Oct 11 07:12:13 EDT 2007
+ writer.addDocument(createDocument("Document 3", 1192101133000L));
+ // Add the fourth document. text = "Document 4" dateTime = Oct 11 08:02:09 EDT 2007
+ writer.addDocument(createDocument("Document 4", 1192104129000L));
+ // latest doc:
+ // Add the fifth document. text = "Document 5" dateTime = Oct 12 13:25:43 EDT 2007
+ writer.addDocument(createDocument("Document 5", 1192209943000L));
+
+ writer.optimize();
+ writer.close();
+ }
+
+ public void testReverseDateSort() throws Exception {
+ IndexSearcher searcher = new IndexSearcher(directory);
+
+ // Create a Sort object. reverse is set to true.
+ // problem occurs only with SortField.AUTO:
+ Sort sort = new Sort(new SortField(DATE_TIME_FIELD, SortField.AUTO, true));
+
+ QueryParser queryParser = new QueryParser(TEXT_FIELD, new WhitespaceAnalyzer());
+ Query query = queryParser.parse("Document");
+
+ // Execute the search and process the search results.
+ String[] actualOrder = new String[5];
+ Hits hits = searcher.search(query, sort);
+ for (int i = 0; i < hits.length(); i++) {
+ Document document = hits.doc(i);
+ String text = document.get(TEXT_FIELD);
+ actualOrder[i] = text;
+ }
+ searcher.close();
+
+ // Set up the expected order (i.e. Document 5, 4, 3, 2, 1).
+ String[] expectedOrder = new String[5];
+ expectedOrder[0] = "Document 5";
+ expectedOrder[1] = "Document 4";
+ expectedOrder[2] = "Document 3";
+ expectedOrder[3] = "Document 2";
+ expectedOrder[4] = "Document 1";
+
+ assertEquals(Arrays.asList(expectedOrder), Arrays.asList(actualOrder));
+ }
+
+ private static Document createDocument(String text, long time) {
+ Document document = new Document();
+
+ // Add the text field.
+ Field textField = new Field(TEXT_FIELD, text, Field.Store.YES, Field.Index.TOKENIZED);
+ document.add(textField);
+
+ // Add the date/time field.
+ String dateTimeString = DateTools.timeToString(time, DateTools.Resolution.SECOND);
+ Field dateTimeField = new Field(DATE_TIME_FIELD, dateTimeString, Field.Store.YES,
+ Field.Index.UN_TOKENIZED);
+ document.add(dateTimeField);
+
+ return document;
+ }
+
+}