Spring data elastic search - Query - Full text search
Asked Answered
G

7

7

I am trying to use elastic search for full text search and Spring data for integrating elastic search with my application.

For example,

There are 6 fields to be indexed.

1)firstName 2)lastName 3)title 4)location 5)industry 6)email

http://localhost:9200/test/_mapping/

I can see these fields in the mapping.

Now, I would like to make a search against these fields with a search input.

For example, When I search "mike 123", it has to search against all these 6 fields.

In Spring data repository,

The below method works to search only in firstName.

Collection<Object> findByFirstNameLike(String searchInput)

But, I would like to search against all the fields.

I tried,

Collection<Object> findByFirstNameLikeOrLastNameLikeOrTitleLikeOrLocationLikeOrIndustryLikeOrEmailLike(String searchInput,String searchInput1,String searchInput2,String searchInput3,)

Here, even the input string is same, i need to pass the same input as 6 params. Also the method name looks bigger with multiple fields.

Is there anyway to make it simple with @Query or ....

Like,

Collection<Object> findByInput(String inputString)

Also, boosting should be given for one of the field.

For example,

When i search for "mike mat", if there is any match in the firstName, that should be the first one in the result even there are exact match in the other fields.

Thanks

Glume answered 5/4, 2015 at 19:22 Comment(0)
A
8

Lets suppose your search term is in the variable query, you can use the method search in ElasticsearchRepository.

repo.search(queryStringQuery(query))

to use queryStringQuery use the following import

import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery;

Agitate answered 8/10, 2016 at 10:47 Comment(2)
This only works when query is a complete word, does not work like a containing query.Acuna
Thank you @Roberto, you save my lines of code and lot of efforts.Caucasia
G
5

I found the way to achieve this and posting here. Hope, this would help.

QueryBuilder queryBuilder = boolQuery().should(
                    queryString("Mike Mat").analyzeWildcard(true)
                            .field("firstName", 2.0f).field("lastName").field("title")
                            .field("location").field("industry").field("email"));

Thanks

Glume answered 6/4, 2015 at 16:1 Comment(2)
In which package is the static method queryString available?Bengt
I found queryStringQuery, working same as like queryString.Heedless
U
1

Not a spring-data elasticsearch expert. But I see two directions you can go. The first would be to use the @Query option. That way you can create your own query. The second would be to use the example in the Filter builder section: http://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.misc.filter

Within elasticearch you would want to use the multi_match query: http://www.elastic.co/guide/en/elasticsearch/reference/1.5/query-dsl-multi-match-query.html

In java such a query would look like this:

QueryBuilder qb = multiMatchQuery(
    "kimchy elasticsearch", 
    "user", "message"       
);

Example coming from: http://www.elastic.co/guide/en/elasticsearch/client/java-api/current/query-dsl-queries.html#multimatch

Underlet answered 6/4, 2015 at 12:9 Comment(1)
Thanks for your reply. I found the solution and posting here.Glume
C
1

We can write our own custom query as below. we can specific index, routing value (this is used if alias is used)

SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX)
            .withRoute(yourQueryBuilderHelper.getRouteValue())
            .withQuery(yourQueryBuilderHelper.buildQuery(yourSearchFilterRequestObject))
            .withFilter(yourQueryBuilderHelper.buildFilter(yourSearchFilterRequestObject)).withTypes(TYPE)
            .withSort(yourQueryBuilderHelper.buildSortCriteria(yourSearchFilterRequestObject))
            .withPageable(yourQueryBuilderHelper.buildPaginationCriteria(yourSearchFilterRequestObject)).build();
    FacetedPage<Ticket> searchResults = elasticsearchTemplate.queryForPage(searchQuery, YourDocumentEntity.class);

Its good to use your own queryBuilder helper which can seperate your elasticSearchService from queryBuilder responsibility.

Hope this helps

Thanks

Cornew answered 10/4, 2016 at 14:50 Comment(0)
C
1

QueryBuilder class is helpful to query from spring Dao to elastic search:

import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.index.query.QueryBuilder;

    QueryBuilder qb = QueryBuilders.boolQuery()
            .must(QueryBuilders.termQuery("state", "KA"));
            .must(QueryBuilders.termQuery("content", "test4"))
            .mustNot(QueryBuilders.termQuery("content", "test2"))
            .should(termQuery("content", "test3"));
            .should(termQuery("content", "test3")); 
Cinderella answered 21/10, 2018 at 4:52 Comment(0)
E
1

Try like this, you can even set importance of the field

QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(query)
              .field("name", 2.0f)
              .field("email")
              .field("title")
              .field("jobDescription", 3.0f)
              .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX);
Echoism answered 11/8, 2019 at 0:36 Comment(0)
U
0

Another way is using Query String query

Query searchQuery = new StringQuery(
      "{\"query\":{\"query_string\":{\"query\":\""+ your-query-here + "\"}}}\"");
    
SearchHits<Product> products = elasticsearchOperations.search(
      searchQuery, 
      Product.class,
      IndexCoordinates.of(PRODUCT_INDEX_NAME));

This will search all the field from your document of specified index

Underpass answered 19/11, 2022 at 5:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.