You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2021/02/15 17:10:59 UTC
[lucene-solr] branch branch_8x updated: SOLR-15149: model creation
errors fixes (#2350)
This is an automated email from the ASF dual-hosted git repository.
abenedetti pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new 59deccf SOLR-15149: model creation errors fixes (#2350)
59deccf is described below
commit 59deccf676d34d19a5e0bf20ce3a77b1ff3dd284
Author: Alessandro Benedetti <a....@sease.io>
AuthorDate: Mon Feb 15 18:02:25 2021 +0100
SOLR-15149: model creation errors fixes (#2350)
SOLR-15149: model loading errors fix + tests
(cherry picked from commit 227ef3b39798d00c006539c9bee0e57db34c2871)
---
solr/CHANGES.txt | 2 +
.../org/apache/solr/ltr/model/LTRScoringModel.java | 2 +-
.../org/apache/solr/ltr/model/LinearModel.java | 4 +-
.../solr/ltr/store/rest/ManagedModelStore.java | 17 +++++---
.../linear-model_notExistentFeature.json | 19 +++++++++
.../linear-model_notExistentStore.json | 46 +++++++++++++++++++++
...ultipleadditivetreesmodel_notExistentStore.json | 39 ++++++++++++++++++
.../multipleadditivetreesmodel_unknownFeature.json | 38 +++++++++++++++++
.../org/apache/solr/ltr/model/TestLinearModel.java | 47 ++++++++++++++++++++++
.../ltr/model/TestMultipleAdditiveTreesModel.java | 25 ++++++++++++
10 files changed, 231 insertions(+), 8 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 8b07128..d637468 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -35,6 +35,8 @@ Optimizations
Bug Fixes
---------------------
* SOLR-15078: Fix ExpandComponent behavior when expanding on numeric fields to differentiate '0' group from null group (hossman)
+* SOLR-15149: Better exception handling for LTR model creation errors (Alessandro Benedetti, Christine Poerschke)
+
Other Changes
---------------------
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LTRScoringModel.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LTRScoringModel.java
index 9052ba1..e148759 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LTRScoringModel.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LTRScoringModel.java
@@ -108,7 +108,7 @@ public abstract class LTRScoringModel implements Accountable {
SolrPluginUtils.invokeSetters(model, params.entrySet());
}
} catch (final Exception e) {
- throw new ModelException("Model type does not exist " + className, e);
+ throw new ModelException("Model loading failed for " + className, e);
}
model.validate();
return model;
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LinearModel.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LinearModel.java
index e5b5064..965c0cb 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LinearModel.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/model/LinearModel.java
@@ -80,10 +80,10 @@ public class LinearModel extends LTRScoringModel {
public void setWeights(Object weights) {
@SuppressWarnings({"unchecked"})
- final Map<String,Double> modelWeights = (Map<String,Double>) weights;
+ final Map<String,Number> modelWeights = (Map<String, Number>) weights;
for (int ii = 0; ii < features.size(); ++ii) {
final String key = features.get(ii).getName();
- final Double val = modelWeights.get(key);
+ final Number val = modelWeights.get(key);
featureToWeight[ii] = (val == null ? null : val.floatValue());
}
}
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
index add7021..0627d79 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/store/rest/ManagedModelStore.java
@@ -294,11 +294,18 @@ public class ManagedModelStore extends ManagedResource implements ManagedResourc
return modelMap;
}
- private static Feature lookupFeatureFromFeatureMap(Map<String,Object> featureMap,
- FeatureStore featureStore) {
- final String featureName = (String)featureMap.get(NAME_KEY);
- return (featureName == null ? null
- : featureStore.get(featureName));
+ private static Feature lookupFeatureFromFeatureMap(Map<String, Object> featureMap, FeatureStore featureStore)
+ {
+ final String featureName = (String) featureMap.get(NAME_KEY);
+ Feature extractedFromStore = featureName == null ? null : featureStore.get(featureName);
+ if (extractedFromStore == null) {
+ if (featureStore.getFeatures().isEmpty()) {
+ throw new ModelException("Missing or empty feature store: " + featureStore.getName());
+ } else {
+ throw new ModelException("Feature: " + featureName + " not found in store: " + featureStore.getName());
+ }
+ }
+ return extractedFromStore;
}
@SuppressWarnings("unchecked")
diff --git a/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentFeature.json b/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentFeature.json
new file mode 100644
index 0000000..ffa2528
--- /dev/null
+++ b/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentFeature.json
@@ -0,0 +1,19 @@
+{
+ "class": "org.apache.solr.ltr.model.LinearModel",
+ "name": "6029760550880411648",
+ "store": "test",
+ "features": [
+ {
+ "name": "notExist1"
+ },
+ {
+ "name": "notExist2"
+ }
+ ],
+ "params": {
+ "weights": {
+ "notExist1": 0.0000000000,
+ "notExist2": 0.1000000000
+ }
+ }
+}
diff --git a/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentStore.json b/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentStore.json
new file mode 100644
index 0000000..fa651b3
--- /dev/null
+++ b/solr/contrib/ltr/src/test-files/modelExamples/linear-model_notExistentStore.json
@@ -0,0 +1,46 @@
+{
+ "class": "org.apache.solr.ltr.model.LinearModel",
+ "name": "6029760550880411648",
+ "store": "not_existent_store",
+ "features": [
+ {
+ "name": "title"
+ },
+ {
+ "name": "description"
+ },
+ {
+ "name": "keywords"
+ },
+ {
+ "name": "popularity",
+ "norm": {
+ "class": "org.apache.solr.ltr.norm.MinMaxNormalizer",
+ "params": {
+ "min": "0.0f",
+ "max": "10.0f"
+ }
+ }
+ },
+ {
+ "name": "text"
+ },
+ {
+ "name": "queryIntentPerson"
+ },
+ {
+ "name": "queryIntentCompany"
+ }
+ ],
+ "params": {
+ "weights": {
+ "title": 0.0000000000,
+ "description": 0.1000000000,
+ "keywords": 0.2000000000,
+ "popularity": 0.3000000000,
+ "text": 0.4000000000,
+ "queryIntentPerson": 0.1231231,
+ "queryIntentCompany": 0.12121211
+ }
+ }
+}
diff --git a/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_notExistentStore.json b/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_notExistentStore.json
new file mode 100644
index 0000000..4ec4938
--- /dev/null
+++ b/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_notExistentStore.json
@@ -0,0 +1,39 @@
+{
+ "class":"org.apache.solr.ltr.model.MultipleAdditiveTreesModel",
+ "name":"multipleadditivetreesmodel",
+ "store": "not_existent_store",
+ "features":[
+ { "name": "matchedTitle"},
+ { "name": "constantScoreToForceMultipleAdditiveTreesScoreAllDocs"}
+ ],
+ "params":{
+ "trees": [
+ {
+ "weight" : "1f",
+ "root": {
+ "feature": "matchedTitle",
+ "threshold": "0.5f",
+ "left" : {
+ "value" : "-100"
+ },
+ "right": {
+ "feature" : "constantScoreToForceMultipleAdditiveTreesScoreAllDocs",
+ "threshold": "10.0f",
+ "left" : {
+ "value" : "50"
+ },
+ "right" : {
+ "value" : "75"
+ }
+ }
+ }
+ },
+ {
+ "weight" : "2f",
+ "root": {
+ "value" : "-10"
+ }
+ }
+ ]
+ }
+}
diff --git a/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_unknownFeature.json b/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_unknownFeature.json
new file mode 100644
index 0000000..496d989
--- /dev/null
+++ b/solr/contrib/ltr/src/test-files/modelExamples/multipleadditivetreesmodel_unknownFeature.json
@@ -0,0 +1,38 @@
+{
+ "class":"org.apache.solr.ltr.model.MultipleAdditiveTreesModel",
+ "name":"multipleadditivetreesmodel",
+ "features":[
+ { "name": "notExist1"},
+ { "name": "notExist2"}
+ ],
+ "params":{
+ "trees": [
+ {
+ "weight" : "1f",
+ "root": {
+ "feature": "notExist1",
+ "threshold": "0.5f",
+ "left" : {
+ "value" : "-100"
+ },
+ "right": {
+ "feature" : "notExist2",
+ "threshold": "10.0f",
+ "left" : {
+ "value" : "50"
+ },
+ "right" : {
+ "value" : "75"
+ }
+ }
+ }
+ },
+ {
+ "weight" : "2f",
+ "root": {
+ "value" : "-10"
+ }
+ }
+ ]
+ }
+}
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
index d5950e6..91e033b 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestLinearModel.java
@@ -185,6 +185,29 @@ public class TestLinearModel extends TestRerankBase {
}
@Test
+ public void integerAndLongFeatureWeights_shouldCreateModel() {
+ final List<Feature> features = getFeatures(new String[]
+ {"constant1", "constant5"});
+ final List<Normalizer> norms =
+ new ArrayList<>(Collections.nCopies(features.size(),IdentityNormalizer.INSTANCE));
+
+ final Map<String,Object> weights = new HashMap<>();
+ weights.put("constant1", 100L);
+ weights.put("constant5", 1);
+
+ Map<String,Object> params = new HashMap<>();
+ params.put("weights", weights);
+
+ final LTRScoringModel ltrScoringModel = createLinearModel("test6",
+ features, norms, "test", fstore.getFeatures(),
+ params);
+
+ store.addModel(ltrScoringModel);
+ final LTRScoringModel m = store.getModel("test6");
+ assertEquals(ltrScoringModel, m);
+ }
+
+ @Test
public void emptyFeaturesTest() {
final ModelException expectedException =
new ModelException("no features declared for model test6");
@@ -206,4 +229,28 @@ public class TestLinearModel extends TestRerankBase {
assertEquals(expectedException.toString(), ex.toString());
}
+ @Test
+ public void notExistentStore_shouldThrowMeaningFulException(){
+ final ModelException expectedException =
+ new ModelException("Feature Store not found: not_existent_store");
+
+ ModelException ex = expectThrows(ModelException.class, () -> {
+ createModelFromFiles("linear-model_notExistentStore.json",
+ "features-store-test-model.json");
+ });
+ assertEquals(expectedException.toString(), ex.toString());
+ }
+
+ @Test
+ public void notExistentFeature_shouldThrowMeaningFulException(){
+ final ModelException expectedException =
+ new ModelException("Feature:notExist1 not found in store: test");
+
+ ModelException ex = expectThrows(ModelException.class, () -> {
+ createModelFromFiles("linear-model_notExistentFeature.json",
+ "features-store-test-model.json");
+ });
+ assertEquals(expectedException.toString(), ex.toString());
+ }
+
}
diff --git a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
index 8cb59f2..1cf2798 100644
--- a/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
+++ b/solr/contrib/ltr/src/test/org/apache/solr/ltr/model/TestMultipleAdditiveTreesModel.java
@@ -225,4 +225,29 @@ public class TestMultipleAdditiveTreesModel extends TestRerankBase {
});
assertEquals(expectedException.toString(), ex.toString());
}
+
+ @Test
+ public void multipleAdditiveTreesTestMissingFeatureStore(){
+ final ModelException expectedException =
+ new ModelException("Feature Store not found: not_existent_store");
+
+ ModelException ex = expectThrows(ModelException.class, () -> {
+ createModelFromFiles("multipleadditivetreesmodel_notExistentStore.json",
+ "multipleadditivetreesmodel_features.json");
+ });
+ assertEquals(expectedException.toString(), ex.toString());
+ }
+
+ @Test
+ public void multipleAdditiveTreesTestUnknownFeature(){
+ final ModelException expectedException =
+ new ModelException("Feature:notExist1 not found in store: _DEFAULT_");
+
+ ModelException ex = expectThrows(ModelException.class, () -> {
+ createModelFromFiles("multipleadditivetreesmodel_unknownFeature.json",
+ "multipleadditivetreesmodel_features.json");
+ });
+ assertEquals(expectedException.toString(), ex.toString());
+ }
+
}