How to create a query with query_string using Elasticsearch Java Api - java

Currently my query request body looks like
{
"query": {
"query_string": {
"default_field": "file",
"query": "Email OR #gmail.com #yahoo.com"
}
},
"highlight": {
"fields": {
"file": {
}
}
}
}
My java code looks like
String queryString = "{"
+ "\"query_string\": "
+ "{"
+ "\"default_field\":"
+ " \"file\","
+ " \"query\": \"Email OR #gmail.com #yahoo.com\""
+ "}"
+ "}";
with following API calls
SearchRequestBuilder searchRequestBuilder = client.prepareSearch()
.setIndices("resume")
.setTypes("docs").setQuery(queryString).addHighlightedField("file");
SearchResponse response = searchRequestBuilder.execute().actionGet();
I would prefer a more api based approach for "queryString" part.I am not able to find any api which handles "query_string" part of the request. There are apis for match_all,match, term so on and so forth but not for query_string
Any help would be really appreciated

QueryBuilders is the factory for creating any query including query_string. From documentation:
import static org.elasticsearch.index.query.QueryBuilders.*;
QueryBuilder qb = queryStringQuery("+kimchy -elasticsearch");
Your query would be built as follows:
QueryBuilder qb = queryStringQuery("Email OR #gmail.com #yahoo.com").defaultField("file");
And the full example would be:
SearchRequestBuilder searchRequestBuilder = client.prepareSearch()
.setIndices("resume")
.setTypes("docs").setQuery(qb).addHighlightedField("file");
SearchResponse response = searchRequestBuilder.execute().actionGet();

Related

Mappings field empty in elasticsearch

I am trying to create elasticsearch index using Java API ,
if we see below index mappings filed is coming as empty .
# curl -XGET localhost:9200/initest2
{"initest2":{"aliases":{},**"mappings":{}**,"settings":{"index":{"keyspace":"keyspace_test","number_of_shards":"5","provided_name":"initest2","max_result_window":"10000000","creation_date":"1671025346350","analysis":{"normalizer":{"testnormalizer":{"filter":["asciifolding"],"type":"custom","char_filter":[]}}},"number_of_replicas":"0","uuid":"BK9oTTKETZeWqiuR_tGd8w","version":{"created":"6080499"}}}}}
JAVA code :
String indexQuery = "";
StringBuilder indexString = new StringBuilder("");
String test = "{\"settings\": {\"max_result_window\":10000000,\"keyspace\":\""+keyspaceName+'\u0022' +",\"analysis\": "
+ "{\"normalizer\":{\"testnormalizer\": {\"type\": \"custom\",\"char_filter\": [],\"filter\": [\"asciifolding\"]}}}},"
+ "\"mappings\":{\""+tableName+"\":{\"discover\" : \".*\",\"properties\":{";
indexString.append(test);
for (String i : indexColumns)
{
indexString.append('\u0022'+i+'\u0022' +":" +"{ \"type\": \"keyword\",\"normalizer\": \"testnormalizer\"}" + ",");
}
indexString.delete(indexString.length()-1, indexString.length()).append("}}}}");
indexQuery = indexString.toString();
logger.info("index query is " + indexQuery);
CreateIndexRequest request = new CreateIndexRequest(tableName);
request.source(indexQuery, XContentType.JSON);
CreateIndexResponse createIndexResponse= restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
while printing the query before calling restHighLevel client :
index query is
{"settings": {"max_result_window":10000000,"keyspace":"ndl","analysis": {"normalizer":{"testnormalizer": {"type": "custom","char_filter": [],"filter": ["asciifolding"]}}}},"mappings":{"initest2":{"discover" : ".*","properties":{"name":{ "type": "keyword","normalizer": "testnormalizer"}}}}}
Please assist if any method to be updated in java code / any properties to be updated in elassandra
Current versrion of elasticsearch : 6.8.4
Note : tried using request.settings() & request.mappings() but it didnt help

Elasticsearch match partial text in Java

I have field in elasticsearch "name" which contains for example:
"some text"
I would like to do query which match any partial of this text, for example "some", "so" or "xt"
I was trying do this by queryString:
public Page<View> search(String name, Pageable pageable) {
QueryBuilder queryBuilder = buildQueryFrom(name);
HighlightBuilder highlightBuilder = buildHighlig();
SearchRequestBuilder searchRequest = client.prepareSearch()
.setQuery(queryBuilder)
.highlighter(highlightBuilder)
.setFetchSource(null, new String[]{CV_OCR});
addPageable(searchRequest, pageable);
SearchResponse response = searchRequest.execute().actionGet();
return mapper.mapResponse(response, pageable).map(this::View);
}
private QueryBuilder buildQueryFrom(String text) {
BoolQueryBuilder queryBuilder = boolQuery();
queryBuilder.must(queryStringQuery("*" + text + "*").field("name"));
return queryBuilder;
}
but if I try to search for example "%" or another special character the results are different than my expectations. I was trying also use regex:
private QueryBuilder buildQueryFrom(String text) {
BoolQueryBuilder queryBuilder = boolQuery();
queryBuilder.must(regexpQuery("name", quoteStringAndSetCaseInsensitive(text).pattern()));
return queryBuilder;
}
private Pattern quoteStringAndSetCaseInsensitive(String value) {
return Pattern.compile(Pattern.quote(value), Pattern.CASE_INSENSITIVE);
}
but it didn't work. Is there any other possibility for searching like this?

Search By multiple word using AND operator

This works like a charm :
Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("localhost", 9300));
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("field", "word_1");
fuzzyQueryBuilder.fuzziness(Fuzziness.AUTO);
SearchResponse response = client.prepareSearch("ts_index")
.setTypes("service")
.setQuery(fuzzyQueryBuilder)
.setFrom(0).setSize(60).setExplain(true)
.execute()
.actionGet();
SearchHit[] results = response.getHits().getHits();
But if I want to search by multiple words, it returns nothing, Ex :
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("field", "word_1 word_2");
When I'm using CURL, I've resolved this issue by adding operator to my JSON attributes:
curl -XGET "http://localhost:9200/_search" -d" {\"query\":{\"match\":{\"field\":{\"query\":\"word_1 word_2\",\"fuzziness\":\"AUTO\",\"operator\":\"and\"}}}}
How can I achieve this in Java ?
I believe this is possible with must for AND and should for OR:
QueryBuilder qb = QueryBuilders.boolQuery()
.must(QueryBuilders.fuzzyQuery("field", "word_1"))
.must(QueryBuilders.fuzzyQuery("field", "word_2"));
You can try to build this in a dynamic way with an enum:
public enum MultiQueryBuilder {
OPERATOR_AND {
#Override
public QueryBuilders createQuery(String field, String multiWord) {
String[] words = multiWord.split("\\s+");
QueryBuilder queryBuilder = QueryBuilder.boolQuery();
for(String word : words){
queryBuilder.must(QueryBuilders.fuzzyQuery(field, word));
}
return queryBuilder;
},
OPERATOR_OR {
#Override
public QueryBuilders createQuery(String field, String multiWord) {
String[] words = multiWord.split("\\s+");
QueryBuilder queryBuilder = QueryBuilder.boolQuery();
for(String word : words){
queryBuilder.should(QueryBuilders.fuzzyQuery(field, word));
}
return queryBuilder;
};
public abstract Querybuilders createQuery(String field, String multiWord);
}
You just have to call it in this way:
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders
.fuzzyQuery(MultiQuerybuilder
.valueOf(OPERATOR_AND)
.createQuery("field", "word_1 word_2"));

ElasticSearch Jest client use: MalformedJsonException on any queries

I am trying to use a JEST Client to search the remotely located ElasticSearch index.
However I've ran into a problem - every single query, be it constructed using various builders or just default ES queries, everything returns
com.google.gson.stream.MalformedJsonException
Code:
String URL = "http://api.exiletools.com:80";
String API_KEY = "DEVELOPMENT-Indexer";
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig.Builder(URL)
.defaultCredentials("apikey", API_KEY)
.build());
JestClient client = factory.getObject();
qb = QueryBuilders
.boolQuery()
.must(QueryBuilders.termQuery("attributes.league", "Standard"))
.must(new TermQueryBuilder("attributes.equipType", "Ring"))
.must(new TermQueryBuilder("shop.verified", "yes"));
searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(qb);
query = searchSourceBuilder.toString();
search = new Search.Builder(query).build();
client.execute(search); // Here I get the error
As a final test I just copied the smallest query I could find from Jest integration test examples and just replaced the search terms there, to look like:
query = "{\n"
+ " \"query\" : {\n"
+ " \"term\" : { \"shop.chaosEquiv\" : \"167\" }\n"
+ " }\n"
+ "}";
This query when copied from the output stream looks like this:
{
"query" : {
"term" : { "shop.chaosEquiv" : "167" }
}
}
No trailing whitespaces or anything, looks valid to me.
Still getting the same error.
Can anyone tell what is going on?

Query Elasticsearch using String in java

I am using Elasticsearch maven jar file to query Elasticsearch. But now I want to query the elasticsearch using full generated query string:
query :
{
"bool" : {
"must" : [ {
"term" : {
"title" : "mercedes"
}
}, {
"term" : {
"Doors" : "2"
}
} ]
}
}
How do I use the above query string to query elasticsearch in java?
Following code prepares a boolquery. You should create a SearchRequestBuilder to execute it.
BoolQueryBuilder boolQuery = new BoolQueryBuilder();
boolQuery.must(QueryBuilders.termQuery("title", "mercedes"));
boolQuery.must(QueryBuilders.termQuery("Doors", "2"));
If you want to use query as string without building it in code, you can use following;
String myQuery = "Your Query Here";
SearchSourceBuilder ssb= new SearchSourceBuilder();
search.query(myQuery);
SearchRequestBuilder srb; // You should define srb before next steps
srb.internalBuilder(ssb);
SearchResponse response = srb.execute().actionGet();
I use the following code to query Elasticsearch using JSON string.
SearchResponse response = client.prepareSearch(yourIndexName)
.setSource(yourJsonQueryString)
.execute().actionGet();

Categories

Resources