Spring MVC project with ElasticSearch integration


(Farooq Rahu) #1

Hi All,

I have created project Spring MVC project with ElasticSearch integration.
i am able to save data on elasticsearch-1.7.3 with nested fields now i want to retrieve my lists.

here is my code how i work...

//Storing my data...

List<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
IndexQuery indexQuery1 = new IndexQueryBuilder().withId(userDetail.getUserDetailId()+"")
                    .withObject(userDetail).build();
indexQueries.add(indexQuery1);
elasticsearchTemplate.bulkIndex(indexQueries);

//retrieving my data userDetail have join with user and user have roles.
Page<UserDetail> pageObj;
        if (StringUtils.isBlank(query)) {
            pageObj = userDetailElasticSearchRepository.findAll(pageable);
        } else {
            pageObj = userDetailElasticSearchRepository.findAll(pageable);
        }
        
        logger.info("Size Users:"+pageObj.getContent().size());
        
        model.addAttribute("total", pageObj.getTotalPages());
        model.addAttribute("userdetails", pageObj.getContent());
        model.addAttribute("page", page + 1);

findAll retrieves whole data but i need the data i am saving with different role.

Now trying with the code

        final QueryBuilder builder = nestedQuery("userdetails", boolQuery().must(termQuery("users.roles.name", "ROLE_DATA_ENTRY")).must(termQuery("users.roles.name", "ROLE_ADMIN")));

        final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();

        logger.info("builder:"+builder.toString());            
        logger.info("searchQuery:"+searchQuery);

but still unsuccessful.... Kindly help me to resolve the issue.....


(David Pilato) #2

It depends on your mapping I guess.

ROLE_DATA_ENTRY might have been analyzed with the default analyzer so a Term query won't match here.

What is your mapping?


(Farooq Rahu) #3

Hi David,
Thanks for reply..

This is my mapping of UserDetail it have nested object user and role

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Document(indexName="userdetails")
@Entity
@Table(name = "UserDetail")
public class UserDetail{......
//////

@Field( type = FieldType.Nested)
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "UserId")
private User user;

//////////////
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Document(indexName="users")
@Entity
@Table(name = "User")
public class User {.....

and user have role

@Field( type = FieldType.Nested)
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "UserId")
private Set roles = new HashSet<>();

this query works fine ...without nested object query...

SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("firstName", "farooqfname")).build();
pageObj = userDetailElasticSearchRepository.search(searchQuery);

but i need to search with nested object... i am beginner for elasticsearch....

Yet i don't have much idea of curl how to use it.. kindly write some simple examples....
I have much time worked on only sql, jpql and hql .


(Farooq Rahu) #4

Also i am testing this way too

    final BoolQueryBuilder builder = boolQuery();
    builder.must(nestedQuery("userdetails.users", termQuery("users.userName", "farooqesee")));
    System.out.println("builder:"+builder);
    final SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(builder)
            .build();
    Page<UserDetail> pageObj =  userDetailElasticSearchRepository.search(searchQuery);
    System.out.println("Size Users:"+pageObj.getContent().size());

my query built...

builder:{
"bool" : {
"must" : {
"nested" : {
"query" : {
"term" : {
"users.userName" : "farooqesee"
}
},
"path" : "userdetails.users"
}
}
}
}

But IDE Exception......

searchUser(com.binaryvibes.wms.springapp.UserServiceTest) Time elapsed: 0.195 sec <<< ERROR!
org.elasticsearch.action.search.SearchPhaseExecutionException:

Failed to execute phase [dfs], all shards failed; shardFailures {[Y-0-CO9uQEqHvBWuhfvT8A][userdetails][0]: SearchParseException[[userdetails][0]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"query":{"bool":{"must":{"nested":{"query":{"term":{"users.userName":"farooqesee"}},"path":"userdetails.users"}}}}}]]]; nested:

QueryParsingException[[userdetails] [nested] failed to find nested object under path [userdetails.users]]; }{[Y-0-CO9uQEqHvBWuhfvT8A][userdetails][1]:

SearchParseException[[userdetails][1]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"query":{"bool":{"must":{"nested":{"query":{"term":{"users.userName":"farooqesee"}},"path":"userdetails.users"}}}}}]]]; nested: QueryParsingException[[userdetails] [nested] failed to find nested object under path [userdetails.users]]; }{[Y-0-CO9uQEqHvBWuhfvT8A][userdetails][2]:

SearchParseException[[userdetails][2]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"query":{"bool":{"must":{"nested":{"query":{"term":{"users.userName":"farooqesee"}},"path":"userdetails.users"}}}}}]]]; nested: QueryParsingException[[userdetails] [nested] failed to find nested object under path [userdetails.users]]; }{[Y-0-CO9uQEqHvBWuhfvT8A][userdetails][3]:

SearchParseException[[userdetails][3]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"query":{"bool":{"must":{"nested":{"query":{"term":{"users.userName":"farooqesee"}},"path":"userdetails.users"}}}}}]]]; nested: QueryParsingException[[userdetails] [nested] failed to find nested object under path [userdetails.users]]; }{[Y-0-CO9uQEqHvBWuhfvT8A][userdetails][4]:

SearchParseException[[userdetails][4]: from[0],size[10]: Parse Failure [Failed to parse source [{"from":0,"size":10,"query":{"bool":{"must":{"nested":{"query":{"term":{"users.userName":"farooqesee"}},"path":"userdetails.users"}}}}}]]]; nested: QueryParsingException[[userdetails] [nested] failed to find nested object under path [userdetails.users]]; }
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.onFirstPhaseResult(TransportSearchTypeAction.java:237)
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction$1.onFailure(TransportSearchTypeAction.java:183)
at org.elasticsearch.search.action.SearchServiceTransportAction$23.run(SearchServiceTransportAction.java:565)
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)

ElasticSearch Console Exception...

Caused by: org.elasticsearch.index.query.QueryParsingException: [userdetails] [nested] failed to find nested object under path [userdetails.users]


(David Pilato) #5

Can't really tell without knowing your mapping. But based on your answers I believe you did not define one.

Also I have no idea about what your framework is doing behind the scene. I don't understand how the nested thing is generated (and if you really need it).

And it's so easy to run some CRUD / search operations in Java that I always prefer doing that manually than delegating this to a framework.

( read http://david.pilato.fr/blog/2015/05/09/advanced-search-for-your-legacy-application/ )

I think you are using Hibernate. Have you tried the hibernate search integration with elasticsearch? I think it might be available (unsure though).


(Farooq Rahu) #6

I think i don't have the correct idea of mapping how and where we do that?


(Farooq Rahu) #7

Further i am using JPA Repositories for curd operations .


(Farooq Rahu) #8

and yet have not integrated hibernate search with elasticsearch.

but i am trying ..


(David Pilato) #9

You can start reading here: https://www.elastic.co/guide/en/elasticsearch/guide/master/mapping-intro.html


(Farooq Rahu) #10

Thanks David i am reading and will continue to ask for help....


(system) #11