3131import org .elasticsearch .plugins .Plugin ;
3232import org .elasticsearch .plugins .ScriptPlugin ;
3333import org .elasticsearch .script .ScoreScript ;
34+ import org .elasticsearch .script .ScoreScript .LeafFactory ;
3435import org .elasticsearch .script .ScriptContext ;
3536import org .elasticsearch .script .ScriptEngine ;
37+ import org .elasticsearch .search .lookup .SearchLookup ;
3638
3739/**
3840 * An example script plugin that adds a {@link ScriptEngine} implementing expert scoring.
@@ -53,80 +55,105 @@ public String getType() {
5355 }
5456
5557 @ Override
56- public <T > T compile (String scriptName , String scriptSource , ScriptContext <T > context , Map <String , String > params ) {
58+ public <T > T compile (String scriptName , String scriptSource ,
59+ ScriptContext <T > context , Map <String , String > params ) {
5760 if (context .equals (ScoreScript .CONTEXT ) == false ) {
58- throw new IllegalArgumentException (getType () + " scripts cannot be used for context [" + context .name + "]" );
61+ throw new IllegalArgumentException (getType ()
62+ + " scripts cannot be used for context ["
63+ + context .name + "]" );
5964 }
6065 // we use the script "source" as the script identifier
6166 if ("pure_df" .equals (scriptSource )) {
62- ScoreScript .Factory factory = (p , lookup ) -> new ScoreScript .LeafFactory () {
63- final String field ;
64- final String term ;
65- {
66- if (p .containsKey ("field" ) == false ) {
67- throw new IllegalArgumentException ("Missing parameter [field]" );
68- }
69- if (p .containsKey ("term" ) == false ) {
70- throw new IllegalArgumentException ("Missing parameter [term]" );
71- }
72- field = p .get ("field" ).toString ();
73- term = p .get ("term" ).toString ();
74- }
67+ ScoreScript .Factory factory = PureDfLeafFactory ::new ;
68+ return context .factoryClazz .cast (factory );
69+ }
70+ throw new IllegalArgumentException ("Unknown script name "
71+ + scriptSource );
72+ }
7573
76- @ Override
77- public ScoreScript newInstance (LeafReaderContext context ) throws IOException {
78- PostingsEnum postings = context .reader ().postings (new Term (field , term ));
79- if (postings == null ) {
80- // the field and/or term don't exist in this segment, so always return 0
81- return new ScoreScript (p , lookup , context ) {
82- @ Override
83- public double execute () {
84- return 0.0d ;
85- }
86- };
74+ @ Override
75+ public void close () {
76+ // optionally close resources
77+ }
78+
79+ private static class PureDfLeafFactory implements LeafFactory {
80+ private final Map <String , Object > params ;
81+ private final SearchLookup lookup ;
82+ private final String field ;
83+ private final String term ;
84+
85+ private PureDfLeafFactory (
86+ Map <String , Object > params , SearchLookup lookup ) {
87+ if (params .containsKey ("field" ) == false ) {
88+ throw new IllegalArgumentException (
89+ "Missing parameter [field]" );
90+ }
91+ if (params .containsKey ("term" ) == false ) {
92+ throw new IllegalArgumentException (
93+ "Missing parameter [term]" );
94+ }
95+ this .params = params ;
96+ this .lookup = lookup ;
97+ field = params .get ("field" ).toString ();
98+ term = params .get ("term" ).toString ();
99+ }
100+
101+ @ Override
102+ public boolean needs_score () {
103+ return false ; // Return true if the script needs the score
104+ }
105+
106+ @ Override
107+ public ScoreScript newInstance (LeafReaderContext context )
108+ throws IOException {
109+ PostingsEnum postings = context .reader ().postings (
110+ new Term (field , term ));
111+ if (postings == null ) {
112+ /*
113+ * the field and/or term don't exist in this segment,
114+ * so always return 0
115+ */
116+ return new ScoreScript (params , lookup , context ) {
117+ @ Override
118+ public double execute () {
119+ return 0.0d ;
87120 }
88- return new ScoreScript (p , lookup , context ) {
89- int currentDocid = -1 ;
90- @ Override
91- public void setDocument (int docid ) {
92- // advance has undefined behavior calling with a docid <= its current docid
93- if (postings .docID () < docid ) {
94- try {
95- postings .advance (docid );
96- } catch (IOException e ) {
97- throw new UncheckedIOException (e );
98- }
99- }
100- currentDocid = docid ;
101- }
102- @ Override
103- public double execute () {
104- if (postings .docID () != currentDocid ) {
105- // advance moved past the current doc, so this doc has no occurrences of the term
106- return 0.0d ;
107- }
108- try {
109- return postings .freq ();
110- } catch (IOException e ) {
111- throw new UncheckedIOException (e );
112- }
121+ };
122+ }
123+ return new ScoreScript (params , lookup , context ) {
124+ int currentDocid = -1 ;
125+ @ Override
126+ public void setDocument (int docid ) {
127+ /*
128+ * advance has undefined behavior calling with
129+ * a docid <= its current docid
130+ */
131+ if (postings .docID () < docid ) {
132+ try {
133+ postings .advance (docid );
134+ } catch (IOException e ) {
135+ throw new UncheckedIOException (e );
113136 }
114- };
137+ }
138+ currentDocid = docid ;
115139 }
116-
117140 @ Override
118- public boolean needs_score () {
119- return false ;
141+ public double execute () {
142+ if (postings .docID () != currentDocid ) {
143+ /*
144+ * advance moved past the current doc, so this doc
145+ * has no occurrences of the term
146+ */
147+ return 0.0d ;
148+ }
149+ try {
150+ return postings .freq ();
151+ } catch (IOException e ) {
152+ throw new UncheckedIOException (e );
153+ }
120154 }
121155 };
122- return context .factoryClazz .cast (factory );
123156 }
124- throw new IllegalArgumentException ("Unknown script name " + scriptSource );
125- }
126-
127- @ Override
128- public void close () {
129- // optionally close resources
130157 }
131158 }
132159 // end::expert_engine
0 commit comments