clone the entire serach context for rewriting

This commit is contained in:
Simon Willnauer 2016-10-05 12:14:48 +02:00
parent 4000a4a106
commit 5687549ad8
4 changed files with 36 additions and 5 deletions

View File

@ -137,6 +137,10 @@ public class QueryRewriteContext implements ParseFieldMatcherSupplier {
this.executionMode.set(Boolean.TRUE); this.executionMode.set(Boolean.TRUE);
} }
/**
* This method fails if {@link #setExecutionMode()} is called before on this context.
* This is used to <i>seal</i>
*/
protected void failIfExecutionMode() { protected void failIfExecutionMode() {
this.cachable = false; this.cachable = false;
if (executionMode.get() == Boolean.TRUE) { if (executionMode.get() == Boolean.TRUE) {

View File

@ -335,11 +335,17 @@ public class QueryShardContext extends QueryRewriteContext {
return indexSettings.getIndex(); return indexSettings.getIndex();
} }
/**
* Compiles (or retrieves from cache) and executes the provided script
*/
public SearchScript getSearchScript(Script script, ScriptContext context, Map<String, String> params) { public SearchScript getSearchScript(Script script, ScriptContext context, Map<String, String> params) {
failIfExecutionMode(); failIfExecutionMode();
return scriptService.search(lookup(), script, context, params); return scriptService.search(lookup(), script, context, params);
} }
/**
* Returns a lazily created {@link SearchScript} that is compiled immediately but can be pulled later once all
* parameters are available.
*/
public Function<Map<String, Object>, SearchScript> getLazySearchScript(Script script, ScriptContext context, public Function<Map<String, Object>, SearchScript> getLazySearchScript(Script script, ScriptContext context,
Map<String, String> params) { Map<String, String> params) {
failIfExecutionMode(); failIfExecutionMode();
@ -347,11 +353,18 @@ public class QueryShardContext extends QueryRewriteContext {
return (p) -> scriptService.search(lookup(), compile, p); return (p) -> scriptService.search(lookup(), compile, p);
} }
/**
* Compiles (or retrieves from cache) and executes the provided script
*/
public ExecutableScript getExecutableScript(Script script, ScriptContext context, Map<String, String> params) { public ExecutableScript getExecutableScript(Script script, ScriptContext context, Map<String, String> params) {
failIfExecutionMode(); failIfExecutionMode();
return scriptService.executable(script, context, params); return scriptService.executable(script, context, params);
} }
/**
* Returns a lazily created {@link ExecutableScript} that is compiled immediately but can be pulled later once all
* parameters are available.
*/
public Function<Map<String, Object>, ExecutableScript> getLazyExecutableScript(Script script, ScriptContext context, public Function<Map<String, Object>, ExecutableScript> getLazyExecutableScript(Script script, ScriptContext context,
Map<String, String> params) { Map<String, String> params) {
failIfExecutionMode(); failIfExecutionMode();

View File

@ -172,6 +172,13 @@ final class DefaultSearchContext extends SearchContext {
queryShardContext.setTypes(request.types()); queryShardContext.setTypes(request.types());
} }
DefaultSearchContext(DefaultSearchContext source) {
this(source.id(), source.request(), source.shardTarget(), source.engineSearcher, source.indexService, source.indexShard(),
source.bigArrays(), source.timeEstimateCounter(), source.parseFieldMatcher(), source.timeout(), source.fetchPhase());
}
@Override @Override
public void doClose() { public void doClose() {
// clear and scope phase we have // clear and scope phase we have

View File

@ -517,11 +517,18 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv
} }
final SearchContext createContext(ShardSearchRequest request, @Nullable Engine.Searcher searcher) throws IOException { final SearchContext createContext(ShardSearchRequest request, @Nullable Engine.Searcher searcher) throws IOException {
final DefaultSearchContext context = createSearchContext(request, defaultSearchTimeout, searcher);
DefaultSearchContext context = createSearchContext(request, defaultSearchTimeout, searcher);
SearchContext.setCurrent(context);
try { try {
request.rewrite(new QueryShardContext(context.getQueryShardContext())); // we clone the search context here just for rewriting otherwise we
// might end up with incorrect state since we are using now() or script services
// during rewrite and normalized / evaluate templates etc.
// NOTE this context doesn't need to be closed - the outer context will
// take care of this.
DefaultSearchContext rewriteContext = new DefaultSearchContext(context);
SearchContext.setCurrent(rewriteContext);
request.rewrite(rewriteContext.getQueryShardContext());
SearchContext.setCurrent(context);
assert context.getQueryShardContext().isCachable();
if (request.scroll() != null) { if (request.scroll() != null) {
context.scrollContext(new ScrollContext()); context.scrollContext(new ScrollContext());
context.scrollContext().scroll = request.scroll(); context.scrollContext().scroll = request.scroll();