Java源码示例:org.apache.lucene.expressions.js.JavascriptCompiler

示例1
public void testBoostsAreAppliedLast() throws Exception {

    SimpleBindings bindings = new SimpleBindings();
    bindings.add("score", DoubleValuesSource.SCORES);
    Expression expr = JavascriptCompiler.compile("ln(score + 4)");

    Query q1 = new FunctionScoreQuery(new TermQuery(new Term(TEXT_FIELD, "text")), expr.getDoubleValuesSource(bindings));
    TopDocs plain = searcher.search(q1, 5);

    Query boosted = new BoostQuery(q1, 2);
    TopDocs afterboost = searcher.search(boosted, 5);
    assertEquals(plain.totalHits.value, afterboost.totalHits.value);
    for (int i = 0; i < 5; i++) {
      assertEquals(plain.scoreDocs[i].doc, afterboost.scoreDocs[i].doc);
      assertEquals(plain.scoreDocs[i].score, afterboost.scoreDocs[i].score / 2, 0.0001);
    }

  }
 
示例2
public void testAccessToValueSource() throws Exception {

    FunctionScoreQuery q1 = new FunctionScoreQuery(new TermQuery(new Term(TEXT_FIELD, "a")), DoubleValuesSource.constant(31));
    Query q2 = new FunctionScoreQuery(q1.getWrappedQuery(), q1.getSource());
    QueryUtils.check(q2);
    QueryUtils.checkEqual(q2, q1);

    FunctionScoreQuery q3 = new FunctionScoreQuery(new TermQuery(new Term(TEXT_FIELD, "first")),
            DoubleValuesSource.fromIntField(INT_FIELD));
    Query q4 = new FunctionScoreQuery(q3.getWrappedQuery(), q3.getSource());
    QueryUtils.checkEqual(q3, q4);

    SimpleBindings bindings = new SimpleBindings();
    bindings.add("score", DoubleValuesSource.SCORES);
    Expression expr = JavascriptCompiler.compile("ln(score + 4)");
    FunctionScoreQuery q5 = new FunctionScoreQuery(new TermQuery(new Term(TEXT_FIELD, "text")), expr.getDoubleValuesSource(bindings));
    Query q6 = new FunctionScoreQuery(q5.getWrappedQuery(), q5.getSource());
    QueryUtils.checkEqual(q5, q6);


  }
 
示例3
/** tests the returned sort values are correct */
public void testSortValues() throws Exception {
  Expression expr = JavascriptCompiler.compile("sqrt(_score)");
  
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("_score", DoubleValuesSource.SCORES);

  Sort sort = new Sort(expr.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  TopFieldDocs td = searcher.search(query, 3, sort, true);
  for (int i = 0; i < 3; i++) {
    FieldDoc d = (FieldDoc) td.scoreDocs[i];
    float expected = (float) Math.sqrt(d.score);
    float actual = ((Double)d.fields[0]).floatValue();
    assertEquals(expected, actual, 0d);
  }
}
 
示例4
/** tests same binding used more than once in an expression */
public void testTwoOfSameBinding() throws Exception {
  Expression expr = JavascriptCompiler.compile("_score + _score");
  
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("_score", DoubleValuesSource.SCORES);
  
  Sort sort = new Sort(expr.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  TopFieldDocs td = searcher.search(query, 3, sort, true);
  for (int i = 0; i < 3; i++) {
    FieldDoc d = (FieldDoc) td.scoreDocs[i];
    float expected = 2*d.score;
    float actual = ((Double)d.fields[0]).floatValue();
    assertEquals(expected, actual, 0d);
  }
}
 
示例5
/** Uses variables with $ */
public void testDollarVariable() throws Exception {
  Expression expr = JavascriptCompiler.compile("$0+$score");
  
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("$0", DoubleValuesSource.SCORES);
  bindings.add("$score", DoubleValuesSource.SCORES);

  Sort sort = new Sort(expr.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  TopFieldDocs td = searcher.search(query, 3, sort, true);
  for (int i = 0; i < 3; i++) {
    FieldDoc d = (FieldDoc) td.scoreDocs[i];
    float expected = 2*d.score;
    float actual = ((Double)d.fields[0]).floatValue();
    assertEquals(expected, actual, 0d);
  }
}
 
示例6
/** tests expression referring to another expression */
public void testExpressionRefersToExpression() throws Exception {
  Expression expr1 = JavascriptCompiler.compile("_score");
  Expression expr2 = JavascriptCompiler.compile("2*expr1");
  
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("_score", DoubleValuesSource.SCORES);
  bindings.add("expr1", expr1);
  
  Sort sort = new Sort(expr2.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  TopFieldDocs td = searcher.search(query, 3, sort, true);
  for (int i = 0; i < 3; i++) {
    FieldDoc d = (FieldDoc) td.scoreDocs[i];
    float expected = 2*d.score;
    float actual = ((Double)d.fields[0]).floatValue();
    assertEquals(expected, actual, 0d);
  }
}
 
示例7
private void doTestLotsOfBindings(int n) throws Exception {
  SimpleBindings bindings = new SimpleBindings();    
  StringBuilder sb = new StringBuilder();
  for (int i = 0; i < n; i++) {
    if (i > 0) {
      sb.append("+");
    }
    sb.append("x" + i);
    bindings.add("x" + i, DoubleValuesSource.SCORES);
  }
  
  Expression expr = JavascriptCompiler.compile(sb.toString());
  Sort sort = new Sort(expr.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  TopFieldDocs td = searcher.search(query, 3, sort, true);
  for (int i = 0; i < 3; i++) {
    FieldDoc d = (FieldDoc) td.scoreDocs[i];
    float expected = n*d.score;
    float actual = ((Double)d.fields[0]).floatValue();
    assertEquals(expected, actual, 0d);
  }
}
 
示例8
public void testDoubleValuesSourceTypes() throws Exception {
  Expression expr = JavascriptCompiler.compile("2*popularity + count");
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("popularity", DoubleValuesSource.fromLongField("popularity"));
  bindings.add("count", DoubleValuesSource.fromLongField("count"));
  DoubleValuesSource vs = expr.getDoubleValuesSource(bindings);

  assertEquals(1, reader.leaves().size());
  LeafReaderContext leaf = reader.leaves().get(0);
  DoubleValues values = vs.getValues(leaf, null);

  assertTrue(values.advanceExact(0));
  assertEquals(10, values.doubleValue(), 0);
  assertTrue(values.advanceExact(1));
  assertEquals(41, values.doubleValue(), 0);
  assertTrue(values.advanceExact(2));
  assertEquals(4, values.doubleValue(), 0);
}
 
示例9
/** User runs a query and aggregates facets. */
private FacetResult search() throws IOException, ParseException {
  DirectoryReader indexReader = DirectoryReader.open(indexDir);
  IndexSearcher searcher = new IndexSearcher(indexReader);
  TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);

  // Aggregate categories by an expression that combines the document's score
  // and its popularity field
  Expression expr = JavascriptCompiler.compile("_score * sqrt(popularity)");
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("_score", DoubleValuesSource.SCORES); // the score of the document
  bindings.add("popularity", DoubleValuesSource.fromLongField("popularity")); // the value of the 'popularity' field

  // Aggregates the facet values
  FacetsCollector fc = new FacetsCollector(true);

  // MatchAllDocsQuery is for "browsing" (counts facets
  // for all non-deleted docs in the index); normally
  // you'd use a "normal" query:
  FacetsCollector.search(searcher, new MatchAllDocsQuery(), 10, fc);

  // Retrieve results
  Facets facets = new TaxonomyFacetSumValueSource(taxoReader, config, fc, expr.getDoubleValuesSource(bindings));
  FacetResult result = facets.getTopChildren(10, "A");
  
  indexReader.close();
  taxoReader.close();
  
  return result;
}
 
示例10
private DoubleValuesSource getDistanceValueSource() {
  Expression distance;
  try {
    distance = JavascriptCompiler.compile(
                "haversin(" + ORIGIN_LATITUDE + "," + ORIGIN_LONGITUDE + ",latitude,longitude)");
  } catch (ParseException pe) {
    // Should not happen
    throw new RuntimeException(pe);
  }
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("latitude", DoubleValuesSource.fromDoubleField("latitude"));
  bindings.add("longitude", DoubleValuesSource.fromDoubleField("longitude"));

  return distance.getDoubleValuesSource(bindings);
}
 
示例11
public void testToString() throws Exception {
  Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
  
  SimpleBindings bindings = new SimpleBindings();    
  bindings.add("_score", DoubleValuesSource.SCORES);
  bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
  
  SortField sf = expr.getSortField(bindings, true);
  assertEquals("<expr(sqrt(_score) + ln(popularity))>!", sf.toString());
}
 
示例12
public void testEquals() throws Exception {
  Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
  
  SimpleBindings bindings = new SimpleBindings();    
  bindings.add("_score", DoubleValuesSource.SCORES);
  bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
  
  SimpleBindings otherBindings = new SimpleBindings();
  otherBindings.add("_score", DoubleValuesSource.fromLongField("_score"));
  otherBindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));

  SortField sf1 = expr.getSortField(bindings, true);
  
  // different order
  SortField sf2 = expr.getSortField(bindings, false);
  assertFalse(sf1.equals(sf2));
  
  // different bindings
  sf2 = expr.getSortField(otherBindings, true);
  assertFalse(sf1.equals(sf2));
  
  // different expression
  Expression other = JavascriptCompiler.compile("popularity/2");
  sf2 = other.getSortField(bindings, true);
  assertFalse(sf1.equals(sf2));
  
  // null
  assertFalse(sf1.equals(null));
  
  // same instance:
  assertEquals(sf1, sf1);
}
 
示例13
public void testBasic() throws Exception {

    // create a sort field and sort by it (reverse order)
    Query query = new TermQuery(new Term("body", "contents"));
    IndexReader r = searcher.getIndexReader();

    // Just first pass query
    TopDocs hits = searcher.search(query, 10);
    assertEquals(3, hits.totalHits.value);
    assertEquals("3", r.document(hits.scoreDocs[0].doc).get("id"));
    assertEquals("1", r.document(hits.scoreDocs[1].doc).get("id"));
    assertEquals("2", r.document(hits.scoreDocs[2].doc).get("id"));

    // Now, rescore:

    Expression e = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
    SimpleBindings bindings = new SimpleBindings();
    bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
    bindings.add("_score", DoubleValuesSource.SCORES);
    Rescorer rescorer = e.getRescorer(bindings);

    hits = rescorer.rescore(searcher, hits, 10);
    assertEquals(3, hits.totalHits.value);
    assertEquals("2", r.document(hits.scoreDocs[0].doc).get("id"));
    assertEquals("1", r.document(hits.scoreDocs[1].doc).get("id"));
    assertEquals("3", r.document(hits.scoreDocs[2].doc).get("id"));

    String expl = rescorer.explain(searcher,
                                   searcher.explain(query, hits.scoreDocs[0].doc),
                                   hits.scoreDocs[0].doc).toString();

    // Confirm the explanation breaks out the individual
    // variables:
    assertTrue(expl.contains("= double(popularity)"));

    // Confirm the explanation includes first pass details:
    assertTrue(expl.contains("= first pass score"));
    assertTrue(expl.contains("body:contents in"));
  }
 
示例14
public void testValidExternals() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("valid0", DoubleValuesSource.fromIntField("valid0"));
  bindings.add("valid1", DoubleValuesSource.fromIntField("valid1"));
  bindings.add("valid2", DoubleValuesSource.fromIntField("valid2"));
  bindings.add("_score", DoubleValuesSource.SCORES);
  bindings.add("valide0", JavascriptCompiler.compile("valid0 - valid1 + valid2 + _score"));
  bindings.validate();
  bindings.add("valide1", JavascriptCompiler.compile("valide0 + valid0"));
  bindings.validate();
  bindings.add("valide2", JavascriptCompiler.compile("valide0 * valide1"));
  bindings.validate();
}
 
示例15
public void testInvalidExternal() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("valid", DoubleValuesSource.fromIntField("valid"));
  bindings.add("invalid", JavascriptCompiler.compile("badreference"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Invalid reference"));
}
 
示例16
public void testInvalidExternal2() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("valid", DoubleValuesSource.fromIntField("valid"));
  bindings.add("invalid", JavascriptCompiler.compile("valid + badreference"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Invalid reference"));
}
 
示例17
public void testSelfRecursion() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("cycle0", JavascriptCompiler.compile("cycle0"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Cycle detected"));
}
 
示例18
public void testCoRecursion() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("cycle0", JavascriptCompiler.compile("cycle1"));
  bindings.add("cycle1", JavascriptCompiler.compile("cycle0"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Cycle detected"));
}
 
示例19
public void testCoRecursion2() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("cycle0", JavascriptCompiler.compile("cycle1"));
  bindings.add("cycle1", JavascriptCompiler.compile("cycle2"));
  bindings.add("cycle2", JavascriptCompiler.compile("cycle0"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Cycle detected"));
}
 
示例20
public void testCoRecursion3() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("cycle0", JavascriptCompiler.compile("100"));
  bindings.add("cycle1", JavascriptCompiler.compile("cycle0 + cycle2"));
  bindings.add("cycle2", JavascriptCompiler.compile("cycle0 + cycle1"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Cycle detected"));
}
 
示例21
public void testCoRecursion4() throws Exception {
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("cycle0", JavascriptCompiler.compile("100"));
  bindings.add("cycle1", JavascriptCompiler.compile("100"));
  bindings.add("cycle2", JavascriptCompiler.compile("cycle1 + cycle0 + cycle3"));
  bindings.add("cycle3", JavascriptCompiler.compile("cycle0 + cycle1 + cycle2"));
  IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
    bindings.validate();
  });
  assertTrue(expected.getMessage().contains("Cycle detected"));
}
 
示例22
/** an example of how to rank by an expression */
public void test() throws Exception {
  // compile an expression:
  Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
  
  // we use SimpleBindings: which just maps variables to SortField instances
  SimpleBindings bindings = new SimpleBindings();
  bindings.add("_score", DoubleValuesSource.SCORES);
  bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));

  // create a sort field and sort by it (reverse order)
  Sort sort = new Sort(expr.getSortField(bindings, true));
  Query query = new TermQuery(new Term("body", "contents"));
  searcher.search(query, 3, sort);
}
 
示例23
public void testDoubleValuesSourceEquals() throws Exception {
  Expression expr = JavascriptCompiler.compile("sqrt(a) + ln(b)");

  SimpleBindings bindings = new SimpleBindings();
  bindings.add("a", DoubleValuesSource.fromIntField("a"));
  bindings.add("b", DoubleValuesSource.fromIntField("b"));

  DoubleValuesSource vs1 = expr.getDoubleValuesSource(bindings);
  // same instance
  assertEquals(vs1, vs1);
  // null
  assertFalse(vs1.equals(null));
  // other object
  assertFalse(vs1.equals("foobar"));
  // same bindings and expression instances
  DoubleValuesSource vs2 = expr.getDoubleValuesSource(bindings);
  assertEquals(vs1.hashCode(), vs2.hashCode());
  assertEquals(vs1, vs2);
  // equiv bindings (different instance)
  SimpleBindings bindings2 = new SimpleBindings();
  bindings2.add("a", DoubleValuesSource.fromIntField("a"));
  bindings2.add("b", DoubleValuesSource.fromIntField("b"));
  DoubleValuesSource vs3 = expr.getDoubleValuesSource(bindings2);
  assertEquals(vs1, vs3);
  // different bindings (same names, different types)
  SimpleBindings bindings3 = new SimpleBindings();
  bindings3.add("a", DoubleValuesSource.fromLongField("a"));
  bindings3.add("b", DoubleValuesSource.fromFloatField("b"));
  DoubleValuesSource vs4 = expr.getDoubleValuesSource(bindings3);
  assertFalse(vs1.equals(vs4));
}
 
示例24
public void testRewrite() throws Exception {
  Expression expr = JavascriptCompiler.compile("a");

  ExpressionValueSource rewritingExpressionSource = new ExpressionValueSource(
          new DoubleValuesSource[]{createDoubleValuesSourceMock(true)},
          expr,
          false);
  ExpressionValueSource notRewritingExpressionSource = new ExpressionValueSource(
          new DoubleValuesSource[]{createDoubleValuesSourceMock(false)},
          expr,
          false);

  assertNotSame(rewritingExpressionSource, rewritingExpressionSource.rewrite(null));
  assertSame(notRewritingExpressionSource, notRewritingExpressionSource.rewrite(null));
}
 
示例25
void assertQuery(Query query, Sort sort) throws Exception {
  int size = TestUtil.nextInt(random(), 1, searcher.getIndexReader().maxDoc() / 5);
  TopDocs expected = searcher.search(query, size, sort, random().nextBoolean());
  
  // make our actual sort, mutating original by replacing some of the 
  // sortfields with equivalent expressions
  
  SortField original[] = sort.getSort();
  SortField mutated[] = new SortField[original.length];
  for (int i = 0; i < mutated.length; i++) {
    if (random().nextInt(3) > 0) {
      SortField s = original[i];
      Expression expr = JavascriptCompiler.compile(s.getField());
      SimpleBindings simpleBindings = new SimpleBindings();
      simpleBindings.add(s.getField(), fromSortField(s));
      boolean reverse = s.getType() == SortField.Type.SCORE || s.getReverse();
      mutated[i] = expr.getSortField(simpleBindings, reverse);
    } else {
      mutated[i] = original[i];
    }
  }
  
  Sort mutatedSort = new Sort(mutated);
  TopDocs actual = searcher.search(query, size, mutatedSort, random().nextBoolean());
  CheckHits.checkEqual(query, expected.scoreDocs, actual.scoreDocs);
  
  if (size < actual.totalHits.value) {
    expected = searcher.searchAfter(expected.scoreDocs[size-1], query, size, sort);
    actual = searcher.searchAfter(actual.scoreDocs[size-1], query, size, mutatedSort);
    CheckHits.checkEqual(query, expected.scoreDocs, actual.scoreDocs);
  }
}
 
示例26
public LongValuesSource fromExpression(String weightExpression, Set<SortField> sortFields) {
  Expression expression = null;
  try {
    expression = JavascriptCompiler.compile(weightExpression);
  } catch (ParseException e) {
    throw new RuntimeException(e);
  }
  SimpleBindings bindings = new SimpleBindings();
  for (SortField sortField : sortFields) {
    bindings.add(sortField.getField(), fromSortField(sortField));
  }
  return expression.getDoubleValuesSource(bindings).toLongValuesSource();
}
 
示例27
/** static helper for re-use in sibling trie class */
public static SortField getSortField(final SortField superSort, final SchemaField field) {
  field.checkSortability();
  Expression expr = null;
  try {
    expr = JavascriptCompiler.compile(field.getName() + " % 3");
  } catch (Exception e) {
    throw new RuntimeException("impossible?", e);
  }
  SimpleBindings bindings = new SimpleBindings();
  bindings.add(superSort.getField(), fromSortField(superSort));
  return expr.getSortField(bindings, superSort.getReverse());
}
 
示例28
public static Object compile(String scriptSource) {
    // classloader created here
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(new SpecialPermission());
    }
    return AccessController.doPrivileged(new PrivilegedAction<Expression>() {
        @Override
        public Expression run() {
            try {
                // snapshot our context here, we check on behalf of the expression
                AccessControlContext engineContext = AccessController.getContext();
                ClassLoader loader = getClass().getClassLoader();
                if (sm != null) {
                    loader = new ClassLoader(loader) {
                        @Override
                        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
                            try {
                                engineContext.checkPermission(new ClassPermission(name));
                            } catch (SecurityException e) {
                                throw new ClassNotFoundException(name, e);
                            }
                            return super.loadClass(name, resolve);
                        }
                    };
                }
                // NOTE: validation is delayed to allow runtime vars, and we don't have access to per index stuff here
                return JavascriptCompiler.compile(scriptSource, JavascriptCompiler.DEFAULT_FUNCTIONS, loader);
            } catch (ParseException e) {
                throw convertToScriptException("compile error", scriptSource, scriptSource, e);
            }
        }
    });
}
 
示例29
private static DoubleValuesSource buildProductBoostFields() {
    try {
        SimpleBindings bindings = new SimpleBindings();
        bindings.add("score", DoubleValuesSource.SCORES);
        bindings.add("category_boost", DoubleValuesSource.fromIntField(ProductSearchQueryBuilder.PRODUCT_CATEGORY_FIELD + "_boost"));
        bindings.add("instock_boost", DoubleValuesSource.fromIntField(ProductSearchQueryBuilder.PRODUCT_SHOP_INSTOCK_FIELD + "_boost"));
        bindings.add("feature_boost", DoubleValuesSource.fromIntField("featured_boost"));
        return JavascriptCompiler.compile("score * (feature_boost + instock_boost + category_boost)").getDoubleValuesSource(bindings);
    } catch (Exception exp) {
        throw new RuntimeException("Unable to compile PRODUCT_BOOST_FIELDS");
    }
}
 
示例30
private static DoubleValuesSource buildProductSkuBoostFields() {
    try {
        SimpleBindings bindings = new SimpleBindings();
        bindings.add("score", DoubleValuesSource.SCORES);
        bindings.add("rank_boost", DoubleValuesSource.fromIntField("rank_boost"));
        bindings.add("instock_boost", DoubleValuesSource.fromIntField(ProductSearchQueryBuilder.PRODUCT_SHOP_INSTOCK_FIELD + "_boost"));
        bindings.add("feature_boost", DoubleValuesSource.fromIntField("featured_boost"));
        return JavascriptCompiler.compile("score * (feature_boost + instock_boost + rank_boost)").getDoubleValuesSource(bindings);
    } catch (Exception exp) {
        throw new RuntimeException("Unable to compile SKU_BOOST_FIELDS");
    }
}