Created
January 16, 2020 12:04
-
-
Save Arfey/dee6f4fa8b5cd8088f5020d2f9a57099 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package company.evo.elasticsearch.rescore; | |
import org.elasticsearch.common.ParseField; | |
import org.elasticsearch.common.ParsingException; | |
import org.elasticsearch.common.io.stream.StreamInput; | |
import org.elasticsearch.common.io.stream.StreamOutput; | |
import org.elasticsearch.common.xcontent.ConstructingObjectParser; | |
import org.elasticsearch.common.xcontent.XContentBuilder; | |
import org.elasticsearch.common.xcontent.XContentParser; | |
import org.elasticsearch.index.fielddata.IndexFieldData; | |
import org.elasticsearch.index.query.QueryRewriteContext; | |
import org.elasticsearch.index.query.QueryShardContext; | |
import org.elasticsearch.script.ScoreScript; | |
import org.elasticsearch.script.Script; | |
import org.elasticsearch.search.rescore.RescoreContext; | |
import org.elasticsearch.search.rescore.RescorerBuilder; | |
import java.io.IOException; | |
import java.util.Objects; | |
public class GroupingMixupRescorerBuilder extends RescorerBuilder<GroupingMixupRescorerBuilder> { | |
public static final String NAME = "grouping_mixup"; | |
// статичні поля для того щоб ми знали що вони є обов'язковими в запиті | |
private static ParseField GROUPING_FIELD_FIELD = new ParseField("field", "group_field"); | |
private static ParseField RESCORE_SCRIPT_FIELD = new ParseField("rescore_script", "decline_script"); | |
// пишимо парсер який вірно прокидує у білдер аргументи аргументи він бере з 34 рядка | |
private static final ConstructingObjectParser<GroupingMixupRescorerBuilder, Void> PARSER = | |
new ConstructingObjectParser<>( | |
NAME, | |
args -> new GroupingMixupRescorerBuilder((String) args[0], (Script) args[1]) | |
); | |
static { | |
// від порядка у цьому блоці залежить який індекс буде у аргумента | |
PARSER.declareString(ConstructingObjectParser.constructorArg(), GROUPING_FIELD_FIELD); | |
PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> Script.parse(p), RESCORE_SCRIPT_FIELD); | |
} | |
private final String groupByField; | |
private final Script rescoreScript; | |
// для ініціалізації на рутовій ноді | |
GroupingMixupRescorerBuilder(String groupByField, Script rescoreScript) { | |
super(); | |
this.groupByField = groupByField; | |
this.rescoreScript = rescoreScript; | |
} | |
// для шард на які різіслалися запити | |
public GroupingMixupRescorerBuilder(StreamInput in) throws IOException { | |
super(in); | |
// вичитуємо із стріма | |
this.groupByField = in.readString(); | |
this.rescoreScript = new Script(in); | |
} | |
// тут ми описуємо що ми пушаємо у стрім для інших нод (порядок важливий) | |
@Override | |
public void doWriteTo(StreamOutput out) throws IOException { | |
out.writeString(groupByField); | |
rescoreScript.writeTo(out); | |
} | |
// десириалізаці | |
@Override | |
public void doXContent(XContentBuilder builder, Params params) throws IOException { | |
builder.startObject(NAME); | |
builder.field(GROUPING_FIELD_FIELD.getPreferredName(), groupByField); | |
builder.field(RESCORE_SCRIPT_FIELD.getPreferredName(), rescoreScript); | |
builder.endObject(); | |
} | |
@Override | |
public String getWriteableName() { | |
return NAME; | |
} | |
@Override | |
public RescorerBuilder<GroupingMixupRescorerBuilder> rewrite(QueryRewriteContext ctx) { | |
return this; | |
} | |
@Override | |
public RescoreContext innerBuildContext(int windowSize, QueryShardContext context) { | |
// це об'єкт за допомогою якого ми зможемо дістатися до сорса поля (інтерфейс для роботи з полем яке ми вказали) | |
IndexFieldData<?> groupingField = | |
this.groupByField == null ? null : context.getForField(context.fieldMapper(this.groupByField)); | |
ScoreScript.LeafFactory scriptFactory = context.getScriptService() | |
.compile(rescoreScript, ScoreScript.CONTEXT) | |
.newFactory(rescoreScript.getParams(), context.lookup()); | |
return new GroupingMixupRescorer.Context(windowSize, groupingField, scriptFactory); | |
} | |
// для кешування | |
@Override | |
public boolean equals(Object obj) { | |
if (!super.equals(obj)) { | |
return false; | |
} | |
GroupingMixupRescorerBuilder other = (GroupingMixupRescorerBuilder) obj; | |
return groupByField.equals(other.groupByField) | |
&& rescoreScript.equals(other.rescoreScript); | |
} | |
// для кешуванн | |
@Override | |
public int hashCode() { | |
return Objects.hash(super.hashCode(), groupByField, rescoreScript); | |
} | |
// тут пи запускаємо наший кнотекст, його ми запускаємо у плагіні | |
public static GroupingMixupRescorerBuilder fromXContent(XContentParser parser) | |
throws ParsingException | |
{ | |
return PARSER.apply(parser, null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment