Reputation: 329
I wrote below program to understand how elastic search could be used to do full text search. Here when I search for individual words it works right but I want to search for combinations of words and that is not working.
package in.blogspot.randomcompiler.elastic_search_demo;
import in.blogspot.randomcompiler.elastic_search_impl.Event;
import java.util.Date;
import org.elasticsearch.action.count.CountRequestBuilder;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import com.fasterxml.jackson.core.JsonProcessingException;
public class ElasticSearchDemo
{
public static void main( String[] args ) throws JsonProcessingException
{
Client client = new TransportClient()
.addTransportAddress(new InetSocketTransportAddress("localhost", 9301));
DeleteResponse deleteResponse1 = client.prepareDelete("chat-data", "event", "1").execute().actionGet();
DeleteResponse deleteResponse2 = client.prepareDelete("chat-data", "event", "2").execute().actionGet();
DeleteResponse deleteResponse3 = client.prepareDelete("chat-data", "event", "3").execute().actionGet();
Event e1 = new Event("LOGIN", new Date(), "Agent1 logged into chat");
String e1Json = e1.prepareJson();
System.out.println("JSON: " + e1Json);
IndexResponse indexResponse1 = client.prepareIndex("chat-data", "event", "1").setSource(e1Json).execute().actionGet();
printIndexResponse("e1", indexResponse1);
Event e2 = new Event("LOGOUT", new Date(), "Agent1 logged out of chat");
String e2Json = e2.prepareJson();
System.out.println("JSON: " + e2Json);
IndexResponse indexResponse2 = client.prepareIndex("chat-data", "event", "2").setSource(e2Json).execute().actionGet();
printIndexResponse("e2", indexResponse2);
Event e3 = new Event("BREAK", new Date(), "Agent1 went on break in the middle of a chat");
String e3Json = e3.prepareJson();
System.out.println("JSON: " + e3Json);
IndexResponse indexResponse3 = client.prepareIndex("chat-data", "event", "3").setSource(e3Json).execute().actionGet();
printIndexResponse("e3", indexResponse3);
FilterBuilder filterBuilder = FilterBuilders.termFilter("value", "break middle");
SearchRequestBuilder searchBuilder = client.prepareSearch();
searchBuilder.setPostFilter(filterBuilder);
CountRequestBuilder countBuilder = client.prepareCount();
countBuilder.setQuery(QueryBuilders.constantScoreQuery(filterBuilder));
CountResponse countResponse1 = countBuilder.execute().actionGet();
System.out.println("HITS: " + countResponse1.getCount());
SearchResponse searchResponse1 = searchBuilder.execute().actionGet();
SearchHits hits = searchResponse1.getHits();
for(int i=0; i<hits.hits().length; i++) {
SearchHit hit = hits.getAt(i);
System.out.println("[" + i + "] " + hit.getId() + " : " +hit.sourceAsString());
}
client.close();
}
private static void printIndexResponse(String description, IndexResponse response) {
System.out.println("Index response for: " + description);
System.out.println("Index name: " + response.getIndex());
System.out.println("Index type: " + response.getType());
System.out.println("Index id: " + response.getId());
System.out.println("Index version: " + response.getVersion());
}
}
The issue I am facing is that when I search for "break middle" it returns nothing, expectation is that it should return the 3rd event.
I understand that I need to configure a different analyzer rather the default one to make it index appropriately.
Could someone please help me in understanding how to do that. Some complete example would to great to have.
Upvotes: 2
Views: 779
Reputation: 6180
The problem is caused because you are using the Term filter:
FilterBuilder filterBuilder = FilterBuilders.termFilter("value", "break middle");
A Term filter doesn't analyse the data in the query string - so Elasticsearch is looking for the exact string "break middle".
However the third document will probably have been broken down by ES into individual terms as follows:
Agent1
went
on
break
in
the
middle
of
a
chat
to fix the issue, use a filter or query that analyses the string you're passing - for example use a Query_String query or Match query.
For example:
QueryBuilder qb = QueryBuilders.matchQuery("event", "break middle");
or:
QueryBuilder qb = QueryBuilders.queryString("break middle");
See the Java API documentation for Elasticsearch for more info.
Upvotes: 2