How To Create Custom Query Parser As a Plugin?


(Aditya Lukman Afandi) #1

Hai,

i want to create custom query parser in elasticsearch 2.1.0,

how register my parser to elastic as a plugin ?

i try add method onModule in FooPlugin class

public void onModule(IndicesModule indicesModule) {
indicesModule.registerQueryParser(MultipleKeywordQueryParser.class);
}

but still didn't work

please help me, thx


(David Pilato) #2

What does not work?


(Aditya Lukman Afandi) #3

I create custom query "multiple_keyword" in Multiple Keyword Parser

and then register this parser in FooPlugin class using

public void onModule(IndicesModule indicesModule) {
indicesModule.registerQueryParser(MultipleKeywordQueryParser.class);
}

when query using my custome query, getting response

{
"query": {
"multiple_keyword": {
"keyword": [
"cctv",
"cafe"
]
}
}
}

my parser didn't work

how to create customer query parser as plugin ?

please help, thx


(David Pilato) #4

What can you see? In logs? In wherever?

Can't you share more information? May be code? A full script which reproduces your "issue"? Output of your requests...

Again, I don't understand what "my parser didn't work" really means here.


(Aditya Lukman Afandi) #5

sorry my question not complete,

i am following tutorial
https://github.com/earldouglas/elastic-scratchpad/tree/master/query-parser

i just defining new keyword query with static response like above tutorial

but getting message in elasticsearch 2.1.0

{
	"error": {
		"root_cause": [{
			"type": "query_parsing_exception",
			"reason": "No query registered for [custom_query]",
			"index": "foo_index",
			"line": 1,
			"col": 11
		}]
	}
}

CustomQueryParser

public class CustomQueryParser extends QueryStringQueryParser {

	private final ESLogger logger;

	@Inject
	public CustomQueryParser(Settings settings) {
		super(settings);
		logger = Loggers.getLogger(getClass(), settings);
	}
	
	@Override
	public String[] names() {
		String name = "custom_query";
		return new String[] { name, Strings.toCamelCase(name) };
	}

	@Override
	public Query parse(QueryParseContext parseContext) throws IOException,
			QueryParsingException {
		logger.info("CUSTOM QUERY PARSER PARSING CUSTOM QUERY!!!");
		return super.parse(parseContext);
	}
	
}

here my full class FooPlugin who register CustomQueryParser

public class ReadAPIPlugin extends Plugin {
	
	public String name() {
		return "read-api";
	}

	public String description() {
		return "Read API Plugin";
	}
	
	public void onModule(IndicesModule indicesModule) {
		indicesModule.registerQueryParser(CustomQueryParser.class);
	}
	
}

(David Pilato) #6

Is your plugin loaded? What do you see in logs? Can you paste them please?

Also please use the correct formatting (Preformatted text and not Blockquote)


(Aditya Lukman Afandi) #7

My Plugin is read-api and loaded,
the log is :

[2016-01-11 09:51:03,529][INFO ][node                     ] [search16-read1] version[2.1.0], pid[17197], build[72cd1f1/2015-11-18T22:40:03Z]
[2016-01-11 09:51:03,530][INFO ][node                     ] [search16-read1] initializing ...
[2016-01-11 09:51:04,082][INFO ][plugins                  ] [search16-read1] loaded [read-api], sites []
[2016-01-11 09:51:06,405][INFO ][node                     ] [search16-read1] initialized
[2016-01-11 09:51:06,405][INFO ][node                     ] [search16-read1] starting ...
[2016-01-11 09:51:06,536][INFO ][transport                ] [search16-read1] publish_address {192.168.2.48:9399}, bound_addresses {192.168.2.48:9399}
[2016-01-11 09:51:06,543][INFO ][discovery                ] [search16-read1] detik-documents/bNW1RlSITQ6qaIG2OYFtGw
[2016-01-11 09:51:11,704][INFO ][http                     ] [search16-read1] publish_address {203.190.242.223:9230}, bound_addresses {203.190.242.223:9230}
[2016-01-11 09:51:11,706][INFO ][node                     ] [search16-read1] started

this the code with correct formating,

CustomQueryParser.java

public class CustomQueryParser extends QueryStringQueryParser {

	private final ESLogger logger;

	@Inject
	public CustomQueryParser(Settings settings) {
		super(settings);
		logger = Loggers.getLogger(getClass(), settings);
	}
	
	@Override
	public String[] names() {
		String name = "custom_query";
		return new String[] { name, Strings.toCamelCase(name) };
	}

	@Override
	public Query parse(QueryParseContext parseContext) throws IOException,
			QueryParsingException {
		logger.info("CUSTOM QUERY PARSER PARSING CUSTOM QUERY!!!");
		return super.parse(parseContext);
	}
	
}

ReadAPIPlugin.java

public class ReadAPIPlugin extends Plugin {
	
	public String name() {
		return "read-api";
	}

	public String description() {
		return "Read API Plugin";
	}
	
	public void onModule(IndicesModule indicesModule) {
		indicesModule.registerQueryParser(CustomQueryParser.class);
	}
	
}

and the json response with the custom query

 {
    	"error": {
    		"root_cause": [{
    			"type": "query_parsing_exception",
    			"reason": "No query registered for [custom_query]",
    			"index": "foo_index",
    			"line": 1,
    			"col": 11
    		}]
    	}
    }

error log in console

[2016-01-11 10:05:42,513][DEBUG][action.search.type       ] [search16-read1] [news_p1_v2][0], node[71eMv9tkQFexqSWeww4X1g], [P], v[284], s[STARTED], a[id=m01ES8DnQYyXRzxaqcEq7Q]: Failed to execute [org.elasticsearch.action.search.SearchRequest@663f613] lastShard [true]
RemoteTransportException[[search16-allnode][192.168.2.48:9392][indices:data/read/search[phase/query]]]; nested: SearchParseException[failed to parse search source [{"query":{"custom_query":{"query":"baz","fields":["bar"]}}}]]; nested: QueryParsingException[No query registered for [custom_query]];
Caused by: SearchParseException[failed to parse search source [{"query":{"custom_query":{"query":"baz","fields":["bar"]}}}]]; nested: QueryParsingException[No query registered for [custom_query]];
	at org.elasticsearch.search.SearchService.parseSource(SearchService.java:848)
	at org.elasticsearch.search.SearchService.createContext(SearchService.java:651)
	at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:617)
	at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:368)
	at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:368)
	at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:365)
	at org.elasticsearch.transport.netty.MessageChannelHandler$RequestHandler.doRun(MessageChannelHandler.java:299)
	at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: [foo_index] QueryParsingException[No query registered for [custom_query]]
	at org.elasticsearch.index.query.QueryParseContext.parseInnerQuery(QueryParseContext.java:255)
	at org.elasticsearch.index.query.IndexQueryParserService.innerParse(IndexQueryParserService.java:303)
	... 10 more

(David Pilato) #8

Can you add some traces in onModule so we are sure this method is called?

A way to prove it BTW would be to call indicesModule.registerQueryParser(CustomQueryParser.class); twice so it will raise and exception.

May be also add a trace in CustomQueryParser(Settings)?


(system) #9