You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by cp...@apache.org on 2022/10/07 11:31:58 UTC

[solr] branch branch_9x updated: SOLR-13219: Fix NPE in FieldLengthFeature with non-stored/missing fields (#1051)

This is an automated email from the ASF dual-hosted git repository.

cpoerschke pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new 3bec25b57d6 SOLR-13219: Fix NPE in FieldLengthFeature with non-stored/missing fields (#1051)
3bec25b57d6 is described below

commit 3bec25b57d6fbbba05f6d58bba93efcac86763b9
Author: Tomasz Elendt <85...@users.noreply.github.com>
AuthorDate: Fri Oct 7 13:18:28 2022 +0200

    SOLR-13219: Fix NPE in FieldLengthFeature with non-stored/missing fields (#1051)
    
    This commit removes unnecessary check for omitNorm from
    FieldLengthFeatureScorer that otherwise causes NullPointerException
    in FieldLengthFeature for non-stored or missing fields.
    
    (cherry picked from commit d9acc079af26bcbb6e9b2502fd61d8de9cee4572)
---
 solr/CHANGES.txt                                   |  2 +
 .../solr/ltr/feature/FieldLengthFeature.java       | 11 +----
 .../test-files/solr/collection1/conf/schema.xml    |  4 +-
 .../solr/ltr/feature/TestFeatureLogging.java       |  6 +--
 .../solr/ltr/feature/TestFieldLengthFeature.java   | 48 ++++++++++++++++++++--
 5 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 1a217df3e32..a0fad2babea 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -117,6 +117,8 @@ Optimizations
 
 Bug Fixes
 ---------------------
+* SOLR-13219: Fix NPE in FieldLengthFeature with non-stored/missing fields (Nick Veenhof, Tomasz Elendt)
+
 * SOLR-15918: Skip repetitive parent znode creation on config set upload (Mike Drob)
 
 * SOLR-15964: Transient cores: don't evict a core when it's still being used. (David Smiley)
diff --git a/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java b/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
index f4a454f8dfb..e5c565d9dc0 100644
--- a/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
+++ b/solr/modules/ltr/src/java/org/apache/solr/ltr/feature/FieldLengthFeature.java
@@ -19,7 +19,6 @@ package org.apache.solr.ltr.feature;
 import java.io.IOException;
 import java.util.LinkedHashMap;
 import java.util.Map;
-import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.NumericDocValues;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -128,17 +127,9 @@ public class FieldLengthFeature extends Feature {
 
       NumericDocValues norms = null;
 
-      public FieldLengthFeatureScorer(FeatureWeight weight, NumericDocValues norms)
-          throws IOException {
+      public FieldLengthFeatureScorer(FeatureWeight weight, NumericDocValues norms) {
         super(weight, norms);
         this.norms = norms;
-
-        // In the constructor, docId is -1, so using 0 as default lookup
-        final IndexableField idxF = searcher.doc(0).getField(field);
-        if (idxF.fieldType().omitNorms()) {
-          throw new IOException(
-              "FieldLengthFeatures can't be used if omitNorms is enabled (field=" + field + ")");
-        }
       }
 
       @Override
diff --git a/solr/modules/ltr/src/test-files/solr/collection1/conf/schema.xml b/solr/modules/ltr/src/test-files/solr/collection1/conf/schema.xml
index 784335758ea..04f5c8e22f8 100644
--- a/solr/modules/ltr/src/test-files/solr/collection1/conf/schema.xml
+++ b/solr/modules/ltr/src/test-files/solr/collection1/conf/schema.xml
@@ -22,8 +22,8 @@
     <field name="finalScore" type="string" indexed="true" stored="true" multiValued="false"/>
     <field name="finalScoreFloat" type="float" indexed="true" stored="true" multiValued="false"/>
     <field name="field" type="text_general" indexed="true" stored="false" multiValued="false"/>
-    <field name="title" type="text_general" indexed="true" stored="true"/>
-    <field name="description" type="text_general" indexed="true" stored="true"/>
+    <field name="title" type="text_general" indexed="true" stored="false"/>
+    <field name="description" type="text_general" indexed="true" stored="false"/>
     <field name="keywords" type="text_general" indexed="true" stored="true" multiValued="true"/>
     <field name="popularity" type="int" indexed="true" stored="true" />
     <field name="dvIntPopularity" type="int" indexed="false" docValues="true" stored="false" multiValued="false"/>
diff --git a/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFeatureLogging.java b/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFeatureLogging.java
index 054987cd9de..38d833f1817 100644
--- a/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFeatureLogging.java
+++ b/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFeatureLogging.java
@@ -76,7 +76,7 @@ public class TestFeatureLogging extends TestRerankBase {
 
     final SolrQuery query = new SolrQuery();
     query.setQuery("title:bloomberg");
-    query.add("fl", "title,description,id,popularity,[fv]");
+    query.add("fl", "id,popularity,[fv]");
     query.add("rows", "3");
     query.add("debugQuery", "on");
     query.add("rq", "{!ltr reRankDocs=3 model=sum1}");
@@ -84,9 +84,7 @@ public class TestFeatureLogging extends TestRerankBase {
     restTestHarness.query("/query" + query.toQueryString());
     assertJQ(
         "/query" + query.toQueryString(),
-        "/response/docs/[0]/=={'title':'bloomberg bloomberg ', 'description':'bloomberg','id':'7', 'popularity':2,  '[fv]':'"
-            + docs0fv_default_csv
-            + "'}");
+        "/response/docs/[0]/=={'id':'7', 'popularity':2,  '[fv]':'" + docs0fv_default_csv + "'}");
 
     query.remove("fl");
     query.add("fl", "[fv]");
diff --git a/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFieldLengthFeature.java b/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFieldLengthFeature.java
index 77792e12ced..9237beb4cf8 100644
--- a/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFieldLengthFeature.java
+++ b/solr/modules/ltr/src/test/org/apache/solr/ltr/feature/TestFieldLengthFeature.java
@@ -35,9 +35,19 @@ public class TestFieldLengthFeature extends TestRerankBase {
     assertU(adoc("id", "3", "title", "w3", "description", "w3"));
     assertU(adoc("id", "4", "title", "w4", "description", "w4"));
     assertU(adoc("id", "5", "title", "w5", "description", "w5"));
-    assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2"));
-    assertU(adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description", "w1 w2 w3 w4 w5 w8"));
-    assertU(adoc("id", "8", "title", "w1 w1 w1 w2 w2 w8", "description", "w1 w1 w1 w2 w2"));
+    assertU(adoc("id", "6", "title", "w1 w2", "description", "w1 w2", "x_t", "1 2"));
+    assertU(
+        adoc("id", "7", "title", "w1 w2 w3 w4 w5", "description", "w1 w2 w3 w4 w5 w8", "x_t", "1"));
+    assertU(
+        adoc(
+            "id",
+            "8",
+            "title",
+            "w1 w1 w1 w2 w2 w8",
+            "description",
+            "w1 w1 w1 w2 w2",
+            "x_t",
+            "1 2 3"));
     assertU(commit());
   }
 
@@ -154,6 +164,38 @@ public class TestFieldLengthFeature extends TestRerankBase {
     assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='1'");
   }
 
+  @Test
+  public void testRankingDynamicField() throws Exception {
+    loadFeature("dynfield-length", FieldLengthFeature.class.getName(), "{\"field\":\"x_t\"}");
+
+    loadModel(
+        "dynfield-model",
+        LinearModel.class.getName(),
+        new String[] {"dynfield-length"},
+        "{\"weights\":{\"dynfield-length\":1.0}}");
+
+    final SolrQuery query = new SolrQuery();
+    query.setQuery("title:w1");
+    query.add("fl", "*, score");
+    query.add("rows", "4");
+
+    // Normal term match
+    assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='1'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='8'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/id=='6'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='7'");
+    // Normal term match
+
+    query.add("rq", "{!ltr model=dynfield-model reRankDocs=4}");
+
+    assertJQ("/query" + query.toQueryString(), "/response/numFound/==4");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='8'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='6'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[2]/id=='7'");
+    assertJQ("/query" + query.toQueryString(), "/response/docs/[3]/id=='1'");
+  }
+
   @Test
   public void testParamsToMap() throws Exception {
     final LinkedHashMap<String, Object> params = new LinkedHashMap<>();