/** * <p>Optimize the given Elasticsearch query. For example, remove unnecessary * boolean clauses or merged nested ones.</p> * <p>Attention: This method is destructive. It changes the given object in * place.</p> * @param query the query to optimize * @return the optimized query (not necessarily the same object as * <code>query</code>) */ public static JsonObject optimize(JsonObject query) { return (JsonObject)optimize(query, null); }
/** * Optimize a query or an array of queries * @param children a single query or an array of queries * @param parentClause the parent clause in which the children are embedded * @return the optimized query/queries */ private static Object optimizeChildren(Object children, String parentClause) { if (children instanceof JsonArray) { return optimizeChildren((JsonArray)children, parentClause); } else { return optimize((JsonObject)children, parentClause); } }
/** * Optimize an array of queries * @param children the queries to optimize * @param parentClause the parent clause in which the children are embedded * @return the optimized queries */ private static JsonArray optimizeChildren(JsonArray children, String parentClause) { JsonArray copy = new JsonArray(); for (int i = 0; i < children.size(); ++i) { Object c = children.getValue(i); Object newc = optimizeChildren(c, parentClause); if (newc instanceof JsonArray) { // merge optimized array into this one copy.addAll((JsonArray)newc); } else { copy.add(newc); } } return copy; } }
bool.put("should", optimizeChildren(should, "should")); bool.put("must", optimizeChildren(must, "must")); bool.put("must_not", optimizeChildren(must_not, "must_not"));
@Override public JsonObject compileQuery(String search) { JsonObject r = compileQueryNoOptimize(search); return ElasticsearchQueryOptimizer.optimize(r); }
private void expectFixture(String fixture) { URL u = this.getClass().getResource("fixtures/" + fixture + ".json"); String fixtureStr; try { fixtureStr = IOUtils.toString(u, StandardCharsets.UTF_8); } catch (IOException e) { throw new RuntimeException(e); } JsonObject fixtureObj = new JsonObject(fixtureStr); JsonObject query = fixtureObj.getJsonObject("query"); JsonObject expected = fixtureObj.getJsonObject("expected"); JsonObject optimizedQuery = ElasticsearchQueryOptimizer.optimize(query); if (!expected.equals(optimizedQuery)) { System.out.println(Json.encodePrettily(optimizedQuery)); } assertEquals(expected, optimizedQuery); }