Explorar el Código

Allow unsigned long field to use decay functions (#96394)

This change adds support for unsigned long fields (and any fields that can provide numeric data) to 
use decay functions as described by (#89603). This allows mapped fields developed as plugins to also 
have access to this set of functions provided they return IndexNumericFieldData from getForField.

Closes #89603.
Jack Conradson hace 2 años
padre
commit
6cb97a5bb0

+ 6 - 0
docs/changelog/96394.yaml

@@ -0,0 +1,6 @@
+pr: 96394
+summary: Allow unsigned long field to use decay functions
+area: Mapping
+type: enhancement
+issues:
+ - 89603

+ 11 - 11
server/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java

@@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
 import org.elasticsearch.common.xcontent.XContentHelper;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.index.fielddata.FieldData;
+import org.elasticsearch.index.fielddata.IndexFieldData;
 import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
 import org.elasticsearch.index.fielddata.IndexNumericFieldData;
 import org.elasticsearch.index.fielddata.MultiGeoPointValues;
@@ -35,7 +36,6 @@ import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
 import org.elasticsearch.index.mapper.MappedFieldType;
-import org.elasticsearch.index.mapper.NumberFieldMapper;
 import org.elasticsearch.index.query.SearchExecutionContext;
 import org.elasticsearch.search.MultiValueMode;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
@@ -217,15 +217,8 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
             return parseDateVariable(parser, context, fieldType, mode);
         } else if (fieldType instanceof GeoPointFieldType) {
             return parseGeoVariable(parser, context, fieldType, mode);
-        } else if (fieldType instanceof NumberFieldMapper.NumberFieldType) {
-            return parseNumberVariable(parser, context, fieldType, mode);
         } else {
-            throw new ParsingException(
-                parser.getTokenLocation(),
-                "field [{}] is of type [{}], but only numeric types are supported.",
-                fieldName,
-                fieldType
-            );
+            return parseNumberVariable(parser, context, fieldType, mode);
         }
     }
 
@@ -267,8 +260,15 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
                 DecayFunctionBuilder.ORIGIN
             );
         }
-        IndexNumericFieldData numericFieldData = context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
-        return new NumericFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), numericFieldData, mode);
+
+        IndexFieldData<?> indexFieldData = context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
+        if (indexFieldData instanceof IndexNumericFieldData numericFieldData) {
+            return new NumericFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), numericFieldData, mode);
+        } else {
+            throw new IllegalArgumentException(
+                "field [" + fieldName + "] is of type [" + fieldType + "], but only numeric types are supported."
+            );
+        }
     }
 
     private AbstractDistanceScoreFunction parseGeoVariable(

+ 29 - 0
x-pack/plugin/mapper-unsigned-long/src/yamlRestTest/resources/rest-api-spec/test/10_basic.yml

@@ -376,3 +376,32 @@ setup:
               }]
 
   - length: { aggregations.test.buckets: 0 }
+
+---
+"Decay":
+  - skip:
+      features: close_to
+      version: " - 8.8.99"
+      reason: "decay functions not supported for unsigned_long"
+
+  - do:
+      search:
+        index: test1
+        body:
+          size: 10
+          query:
+            function_score:
+              functions: [{
+                "linear": {
+                  "ul": {
+                    "scale": 18000000000000000000.0,
+                    "origin": 12000000000000000000.0
+                  }
+                }
+              }]
+
+  - close_to: { hits.hits.0._score: { value: 0.9228715, error: 0.001 } }
+  - close_to: { hits.hits.1._score: { value: 0.9228715, error: 0.001 } }
+  - close_to: { hits.hits.2._score: { value: 0.8209238, error: 0.001 } }
+  - close_to: { hits.hits.3._score: { value: 0.8209238, error: 0.001 } }
+  - close_to: { hits.hits.4._score: { value: 0.6666667, error: 0.001 } }