You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Erick Erickson <er...@gmail.com> on 2009/01/28 14:55:26 UTC

Re: NullPointerException in FieldDocSortedHitQueue.lessThan with custom SortComparator

Well, just glancing at the code you have no assurance that
cj != null. See below.

On Wed, Jan 28, 2009 at 4:58 AM, ninaS <ni...@gmx.de> wrote:

>
> Hello,
>
> I am using a custom SortComparator implementation where I need to override
> a
> method in order to handle Null values:
>
> @Override
>          public ScoreDocComparator newComparator (final IndexReader reader,
> final
> String fieldname)
>          throws IOException {
>            final String field = fieldname.intern();
>            final Comparable[] cachedValues
>                = FieldCache.DEFAULT.getCustom (reader, field,
> CollatorBasedComparator.this);
>
>            return new ScoreDocComparator() {
>
>                      public int compare (ScoreDoc i, ScoreDoc j) {
>                          Comparable ci= cachedValues[i.doc];
>                          Comparable cj= cachedValues[j.doc];
>
>                          int returnValue =0;
>                          if (ci == null)
>                                  returnValue = (cj==null) ? 0 : 1;
>                                  else
>                                          if (cj == null) returnValue = -1;
>  //
>                          else



*****what guarantee do you have here that cj != null? You test for ci
being null, but not for cj.


>
>                                  returnValue= ci.compareTo(cj);
>
>                          return returnValue;
>                      }
>
>              public Comparable sortValue (ScoreDoc i) {
>                return cachedValues[i.doc];
>              }
>
>              public int sortType(){
>                return org.apache.lucene.search.SortField.CUSTOM;
>              }
>            };
>        }
>
>
> Is there anything wrong about the code? Because I get the exception:
>
> java.lang.NullPointerException
>        at
>
> org.apache.lucene.search.FieldDocSortedHitQueue.lessThan(FieldDocSortedHitQueue.java:164)
>        at
> org.apache.lucene.util.PriorityQueue.upHeap(PriorityQueue.java:139)
>        at org.apache.lucene.util.PriorityQueue.put(PriorityQueue.java:53)
>        at
>
> org.apache.lucene.util.PriorityQueue.insertWithOverflow(PriorityQueue.java:78)
>        at
> org.apache.lucene.util.PriorityQueue.insert(PriorityQueue.java:63)
>        at
> org.apache.lucene.search.MultiSearcher.search(MultiSearcher.java:241)
>        at org.apache.lucene.search.Hits.getMoreDocs(Hits.java:100)
>        at org.apache.lucene.search.Hits.hitDoc(Hits.java:206)
>        at org.apache.lucene.search.Hits.doc(Hits.java:155)
>
> I am using lucene 2.3.1.
>
> Please help me.
>
> Thank you in advance,
>
> Nina
>
> --
> View this message in context:
> http://www.nabble.com/NullPointerException-in-FieldDocSortedHitQueue.lessThan-with-custom-SortComparator-tp21702845p21702845.html
> Sent from the Lucene - Java Users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-user-help@lucene.apache.org
>
>

Re: NullPointerException in FieldDocSortedHitQueue.lessThan with custom SortComparator

Posted by Erick Erickson <er...@gmail.com>.
To quote the guys... "patches are always welcome".

Glad you found a solution
Erick

On Mon, Feb 2, 2009 at 8:35 AM, ninaS <ni...@gmx.de> wrote:

>
> I already found another solution: I don't use a custom SortComparator.
> Another solution would be to define a default value for null.
>
> Would be nice if lucene in future would be able
> to search by null values also if a custom SortComparator is used.
>
> To tell you more:
>
> public class MyComparator extends SortComparator {
>
> ...
>
>  public ScoreDocComparator newComparator (final IndexReader reader, final
> String fieldname)
>  {
>
> throws IOException {
>            final String field = fieldname.intern();
>            final Comparable[] cachedValues
>                = FieldCache.DEFAULT.getCustom (reader, field,
> CollatorBasedComparator.this);
>
>            return new ScoreDocComparator() {
>
>                      public int compare (ScoreDoc i, ScoreDoc j) {
>                          ... // compare and handle nulls
>                       }
>
>              public Comparable sortValue (ScoreDoc i) {
>                return cachedValues[i.doc];
>              }
>
>              public int sortType(){
>                  return org.apache.lucene.search.SortField.CUSTOM;
>              }
>            };
>
>  }
>         @Override
>        protected Comparable getComparable(String text) {
>                return new MyComparable(text); //implements compare(Object
> a, Object b),
> handles nulls
>        }
>
> }
>
> Using such a comparator will cause the exception above mentioned if null
> values appear in the sort field.
>
> That is because:
>
> FieldDocSortedHitQueue 163-166:
>
>  case SortField.CUSTOM:{
>           c = docA.fields[i].compareTo(docB.fields[i]);
>                                     break;
> }
>
> does not check whether docA.fields[i] is null.
>
> As you see in line 134-148:
>
> case SortField.STRING:{
>                                        String s1 = (String) docA.fields[i];
>                                        String s2 = (String) docB.fields[i];
>                                        // null values need to be sorted
> first, because of how
> FieldCache.getStringIndex()
>                                        // works - in that routine, any
> documents without a value in the given
> field are
>                                        // put first.  If both are null, the
> next SortField is used
>                                        if (s1 == null) c = (s2==null) ? 0 :
> -1;
>                                        else if (s2 == null) c = 1;  //
>                                        else if (fields[i].getLocale() ==
> null) {
>                                                c = s1.compareTo(s2);
>                                        } else {
>                                                c = collators[i].compare
> (s1, s2);
>                                        }
>                                        break;
>        }
>
> nulls are handled with the type SortField.STRING.
>
> --
> View this message in context:
> http://www.nabble.com/NullPointerException-in-FieldDocSortedHitQueue.lessThan-with-custom-SortComparator-tp21702845p21789742.html
> Sent from the Lucene - Java Users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-user-help@lucene.apache.org
>
>

Re: NullPointerException in FieldDocSortedHitQueue.lessThan with custom SortComparator

Posted by ninaS <ni...@gmx.de>.
I already found another solution: I don't use a custom SortComparator.
Another solution would be to define a default value for null.

Would be nice if lucene in future would be able 
to search by null values also if a custom SortComparator is used.

To tell you more:

public class MyComparator extends SortComparator {

...

 public ScoreDocComparator newComparator (final IndexReader reader, final
String fieldname)
 {

throws IOException {
	    final String field = fieldname.intern();
	    final Comparable[] cachedValues 
	    	= FieldCache.DEFAULT.getCustom (reader, field,
CollatorBasedComparator.this);
	    
	    return new ScoreDocComparator() {

		      public int compare (ScoreDoc i, ScoreDoc j) {
                         ... // compare and handle nulls
		      }

	      public Comparable sortValue (ScoreDoc i) {
	        return cachedValues[i.doc];
	      }

	      public int sortType(){
	    	  return org.apache.lucene.search.SortField.CUSTOM;
	      }
	    };

 }
	@Override
	protected Comparable getComparable(String text) {
		return new MyComparable(text); //implements compare(Object a, Object b),
handles nulls
	}	

}

Using such a comparator will cause the exception above mentioned if null
values appear in the sort field.

That is because:

FieldDocSortedHitQueue 163-166:

 case SortField.CUSTOM:{
           c = docA.fields[i].compareTo(docB.fields[i]);
                                     break;
} 

does not check whether docA.fields[i] is null.

As you see in line 134-148:

case SortField.STRING:{
					String s1 = (String) docA.fields[i];
					String s2 = (String) docB.fields[i];
					// null values need to be sorted first, because of how
FieldCache.getStringIndex()
					// works - in that routine, any documents without a value in the given
field are
					// put first.  If both are null, the next SortField is used
					if (s1 == null) c = (s2==null) ? 0 : -1;
					else if (s2 == null) c = 1;  // 
					else if (fields[i].getLocale() == null) {
						c = s1.compareTo(s2);
					} else {
						c = collators[i].compare (s1, s2);
					}
					break;
        }

nulls are handled with the type SortField.STRING.

-- 
View this message in context: http://www.nabble.com/NullPointerException-in-FieldDocSortedHitQueue.lessThan-with-custom-SortComparator-tp21702845p21789742.html
Sent from the Lucene - Java Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org


Re: NullPointerException in FieldDocSortedHitQueue.lessThan with custom SortComparator

Posted by Erick Erickson <er...@gmail.com>.
Ah, I see. The indention and lack of braces fooled me.
You might consider making things as easy as possible when
asking people to volunteer their time trying to help you.

Then I'm unsure what's the problem, you could try showing
us the entire stack trace. Have you defined your own compare
function? If so, do you test in that function to see whether the
values you're comparing are actually set in your objects? The
fragment you've posted doesn't really give us enough to help
very much.

Best
Erick

On Mon, Feb 2, 2009 at 4:18 AM, ninaS <ni...@gmx.de> wrote:

>
> That's not true: have a look at the "else"-block.
>
> The problem is that lucene's FieldDocSortedHitQueue does only test for null
> values if uses the type FieldDoc.STRING. With FieldDoc.CUSTOM lucene
> assumes
> ci to be never null:
>
> FieldDocSortedHitQueue 163-166:
>
>        case SortField.CUSTOM:{
>                                        c = docA.fields[i].compareTo
> (docB.fields[i]);
>                                        break;
>        }
>
> If I have null values in the field that I want to sort by: I can not use a
> custom SortComparator.
> --
> View this message in context:
> http://www.nabble.com/NullPointerException-in-FieldDocSortedHitQueue.lessThan-with-custom-SortComparator-tp21702845p21786431.html
> Sent from the Lucene - Java Users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-user-help@lucene.apache.org
>
>

Re: NullPointerException in FieldDocSortedHitQueue.lessThan with custom SortComparator

Posted by ninaS <ni...@gmx.de>.
That's not true: have a look at the "else"-block.

The problem is that lucene's FieldDocSortedHitQueue does only test for null
values if uses the type FieldDoc.STRING. With FieldDoc.CUSTOM lucene assumes
ci to be never null:

FieldDocSortedHitQueue 163-166:

        case SortField.CUSTOM:{
					c = docA.fields[i].compareTo (docB.fields[i]);
					break;
        }

If I have null values in the field that I want to sort by: I can not use a
custom SortComparator.
-- 
View this message in context: http://www.nabble.com/NullPointerException-in-FieldDocSortedHitQueue.lessThan-with-custom-SortComparator-tp21702845p21786431.html
Sent from the Lucene - Java Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org