-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add runtime_script date field #60092
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,6 +210,7 @@ private AbstractDistanceScoreFunction parseVariable(String fieldName, XContentPa | |
|
||
// dates and time and geo need special handling | ||
parser.nextToken(); | ||
// TODO these ain't gonna work with runtime fields | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting scenario that I never though about: scoring based on runtime fields. You already added this to the runtime fields meta issue right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I added it. |
||
if (fieldType instanceof DateFieldMapper.DateFieldType) { | ||
return parseDateVariable(parser, context, fieldType, mode); | ||
} else if (fieldType instanceof GeoPointFieldType) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.runtimefields; | ||
|
||
import org.apache.lucene.index.LeafReaderContext; | ||
import org.apache.lucene.util.ArrayUtil; | ||
import org.elasticsearch.search.lookup.SearchLookup; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* Common base class for script field scripts that return long values. | ||
*/ | ||
public abstract class AbstractLongScriptFieldScript extends AbstractScriptFieldScript { | ||
private long[] values = new long[1]; | ||
private int count; | ||
|
||
public AbstractLongScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) { | ||
super(params, searchLookup, ctx); | ||
} | ||
|
||
/** | ||
* Execute the script for the provided {@code docId}. | ||
*/ | ||
public final void runForDoc(int docId) { | ||
count = 0; | ||
setDocument(docId); | ||
execute(); | ||
} | ||
|
||
/** | ||
* Values from the last time {@link #runForDoc(int)} was called. This array | ||
* is mutable and will change with the next call of {@link #runForDoc(int)}. | ||
* It is also oversized and will contain garbage at all indices at and | ||
* above {@link #count()}. | ||
*/ | ||
public final long[] values() { | ||
return values; | ||
} | ||
|
||
/** | ||
* The number of results produced the last time {@link #runForDoc(int)} was called. | ||
*/ | ||
public final int count() { | ||
return count; | ||
} | ||
|
||
protected void collectValue(long v) { | ||
if (values.length < count + 1) { | ||
values = ArrayUtil.grow(values, count + 1); | ||
} | ||
values[count++] = v; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.runtimefields; | ||
|
||
import org.apache.lucene.index.LeafReaderContext; | ||
import org.elasticsearch.painless.spi.Whitelist; | ||
import org.elasticsearch.painless.spi.WhitelistLoader; | ||
import org.elasticsearch.script.ScriptContext; | ||
import org.elasticsearch.script.ScriptFactory; | ||
import org.elasticsearch.search.lookup.SearchLookup; | ||
|
||
import java.io.IOException; | ||
import java.time.temporal.ChronoField; | ||
import java.time.temporal.TemporalAccessor; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public abstract class DateScriptFieldScript extends AbstractLongScriptFieldScript { | ||
public static final ScriptContext<Factory> CONTEXT = new ScriptContext<>("date_script_field", Factory.class); | ||
|
||
static List<Whitelist> whitelist() { | ||
return List.of(WhitelistLoader.loadFromResourceFiles(RuntimeFieldsPainlessExtension.class, "date_whitelist.txt")); | ||
} | ||
|
||
public static final String[] PARAMETERS = {}; | ||
|
||
public interface Factory extends ScriptFactory { | ||
LeafFactory newFactory(Map<String, Object> params, SearchLookup searchLookup); | ||
} | ||
|
||
public interface LeafFactory { | ||
DateScriptFieldScript newInstance(LeafReaderContext ctx) throws IOException; | ||
} | ||
|
||
public DateScriptFieldScript(Map<String, Object> params, SearchLookup searchLookup, LeafReaderContext ctx) { | ||
super(params, searchLookup, ctx); | ||
} | ||
|
||
public static class Millis { | ||
private final DateScriptFieldScript script; | ||
|
||
public Millis(DateScriptFieldScript script) { | ||
this.script = script; | ||
} | ||
|
||
public void millis(long v) { | ||
script.collectValue(v); | ||
} | ||
} | ||
|
||
public static class Date { | ||
private final DateScriptFieldScript script; | ||
|
||
public Date(DateScriptFieldScript script) { | ||
this.script = script; | ||
} | ||
|
||
public void date(TemporalAccessor v) { | ||
// TemporalAccessor is a nanos API so we have to convert. | ||
long millis = Math.multiplyExact(v.getLong(ChronoField.INSTANT_SECONDS), 1000); | ||
millis = Math.addExact(millis, v.get(ChronoField.NANO_OF_SECOND) / 1_000_000); | ||
script.collectValue(millis); | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting too, at least both of these are around parsing values, which you are making public so that we can reuse for runtime fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we can handle this somehow.