I am here to implement basic elastic search functionality. I went through few examples but could not figure out what might have went wrong. Application builds fine but returns empty results..
Let me know if you find anything wrong in my configurations or search retrieval..
ElasticSearch config:
@Configuration
@EnableElasticsearchRepositories(basePackages = "challenge.repository")
public class ElasticConfiguration {
@Bean
public NodeBuilder nodeBuilder() {
return new NodeBuilder();
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() throws IOException {
File tmpDir = File.createTempFile("elastic", Long.toString(System.nanoTime()));
System.out.println("Temp directory: " + tmpDir.getAbsolutePath());
Settings.Builder elasticsearchSettings =
Settings.settingsBuilder()
.put("http.enabled", "true") // 1
.put("index.number_of_shards", "1")
.put("path.data", new File(tmpDir, "data").getAbsolutePath()) // 2
.put("path.logs", new File(tmpDir, "logs").getAbsolutePath()) // 2
.put("path.work", new File(tmpDir, "work").getAbsolutePath()) // 2
.put("path.home", tmpDir); // 3
return new ElasticsearchTemplate(nodeBuilder()
.local(true)
.settings(elasticsearchSettings.build())
.node()
.client());
}
}
As I am trying to search the content that matches in-between text, below is the SearchQueryBuilder I implemented:
@Component
public class MessageSearchQueryBuilder {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
public List<Messages> getAllMessages(String text) {
QueryBuilder query = QueryBuilders.boolQuery()
.should(
QueryBuilders.queryStringQuery(text)
.lenient(true)
.field("content")
).should(QueryBuilders.queryStringQuery("*" + text + "*")
.lenient(true)
.field("content"));
NativeSearchQuery build = new NativeSearchQueryBuilder()
.withQuery(query)
.build();
List<Messages> messages = elasticsearchTemplate.queryForList(build, Messages.class);
return messages;
}
}
Below is the Loader class that loads the data into repository:
@Component
public class MessageLoader {
@Autowired
ElasticsearchOperations operations;
@Autowired
MessagesRepository messagesRepository;
@Autowired
MessageServiceImpl messageServiceImpl;
@PostConstruct
@Transactional
public void loadAll(){
operations.putMapping(Messages.class);
System.out.println("Loading Data");
messagesRepository.save(getData());
System.out.println(getData());
System.out.printf("Loading Completed");
}
private List<Messages> getData() {
// Principal principal = SecurityContextHolder.getContext().getAuthentication();
return messageServiceImpl.getMyMessagesForSearch(2);//Integer.valueOf(principal.getName()));
}
}
Messages model:
@Document(indexName = "messages", type = "messages", shards = 1)
public class Messages {
@Id
private int id;
private int personId;
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Messages [id=" + id + ", personId=" + personId + ", content="
+ content + "]";
}
}
I have the method called findByContent but I am not using this anywhere as I have my own searchQueryBuilder.. Is this something wrong?
Below is my repository:
public interface MessagesRepository extends ElasticsearchRepository<Messages, Long> {
List<Messages> findByContent(String text);
}
Below is my restAPI which retrieves the search results:
@RestController
@RequestMapping("/rest/api/1.0/messages/search")
public class MessageSearchController {
@Autowired
private MessageSearchQueryBuilder messageSearchQueryBuilder;
@GetMapping(value = "/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Messages> getAllMessages(@PathVariable final String text) {
return messageSearchQueryBuilder.getAllMessages(text);
}
}
I am not finding any clue what I have made wrong in getting the matching search results. Any help is like gods gift.