-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: building search utility
PostPosted: Mon Apr 18, 2005 2:03 pm 
Newbie

Joined: Mon Apr 18, 2005 11:52 am
Posts: 5
I tried searching the forum couldn't found the exact or similar solution. I have a search page (jsp) with free form text field, multi selection boxes and etc. I want to build a search utility class, which can be passed to hibernate layer (seperate from presentaion layer). I don't want to pass hardcoded query to hibernate layer rather want to pass some kind of "SearchQuery" object to hibernate layer, which in turn can fire a query to get the result back. Search paraameters are from different tables so not sure how to use Criteria interface with multiple tables/objects. Could anyone reply with examples? I am not an expert in hibernate so any help would be much appreciated.

Thanks,


Top
 Profile  
 
 Post subject: Re: building search utility
PostPosted: Sat Apr 23, 2005 1:49 pm 
Newbie

Joined: Tue Apr 20, 2004 8:15 pm
Posts: 4
I've done this exact same thing for searching on my site, except I don't use the Criteria object. However, I do use the Criteria in 99% of all my other db related options, so I might be able to offer some insight as to what I've done.

First, my 'search engine' presents the same object to the view across different tables as well as sections. I search across content as well as other non-content tables that contain various demographics on companies for our industry. In order to get the back end correct, I had to create an Interface and Wrapper impl objects so the db would always have one type of object to return. In this object, I wrap the individual result rows, the current index number of what page in the db I'm on (offset), the total count of rows found, and the page size the user has specified. And this approach has served me well so far. It has allowed me the typical search results paradigm that everyone expects on a web site.

I have two forms: a simple one field search everything form, and a 'advanced' form that will pick across our company demographics as well as content tables. To get the best speed out of my search, I actually use jdbc->stored proc, but I could have easily used Criteria objs.

From the form I have two objects, based on the search type:
Code:
SimpleQuery
AdvancedQuery


These two objects have various user specified input values like offset, row limit, and the search terms entered. They also have two fields:
Code:
<type>Query
Original<type>Query
(replace type w/Simple or Advanced)

These methods provide in and out query conversion. My controller will pass the various request params and either of these objects to the necessary parser object. The parser is responsible for, obviously, parsing out the key words and taking care of terms like NOT, AND, etc. It will also deal with quotes, parens, and wildcards. Once I have the terms of a query parsed out, I either assign them to other minor objects where I can associate a condition to them or I just have a List of the terms that I can go thru on the DAO level. If you're interested more in parsing, then there's a pretty good book called 'Building Parsers With Java' (ISBN:0201719622 ) - my parsers are all based on concepts from this book.

At the back level I have a SearchDAO that handles the construction of the query. Now, to get to what you're interested in. I would think it would be possible somwhere in the chain from user input to DAO level that you can specify a table name somewhere. Once you have the name, it could be easy to specify the criteria to pick off that table like so:

Code:
SearchDAO:

public CommonResultInterface search(QueryObject queryObj){

// We'll use two objects that implement CommonResultInterface
// UserResults
// GroupResults

// Whatever code u use to get session here

// I'm assuming the table name has an associated object name

Class class = Class.forName(queryObj.getTable());
Criteria crit=session.createCriteria(class);

if(queryObj.getTable().equals("com.company.entity.Users")){

  crit.add( Expression.eq("name", queryObject.getParam("name")) );
  crit.addOrder( Order.asc("groupId") );
  List list = crit.list();

  UserResults userResults = new UserResults();
  // Set the number of results we're returning here
  // I also run separate count queries before this step to set a
  // 'total records' value for the user and whatever else I need
  userResults.setResultsReturned(list.size());
  userResults.setResultType("USER");

  Iterator it = list.iterator();
   while(it.hasNext()){
     // This is where you could get specifc props from your user table
     // or even just add the Users object itself to the results
     UserObjectWrapper uobj = new UserObjectWrapper();
     Users user = (Users)it.next()
     uobj.setName(user.getName());
     uobj.setLogin(user.getLoginId());
     userResults.add(uobj);
   }
   // Do whatever here to close your hibernate session
   return users;

  }else if(queryObj.getTable().equals("com.company.entity.Groups")){
   crit.add( Expression.eq("grpId", queryObject.getParam("groupName")) );
   List list = crit.list();
   // similar code as above here 
  }

}


Now, this is all kinda off the cuff, but I do similar things in my code. I think the main thing is to be able to define the proper Interface (if possible) so you can use one method to do your searching. This has worked great for me as in my interface I have a mandated field called
Code:
resultType
that I check in the view and based on that, display the necessary results. This could also be checked by the controller and then based on this, it could return a specific view that only dealt with displaying specifc info.

Also, you'll have to make sure that if you want to use different tables as I've sorta shown above, you'll just have to get the proper class from the entity/table name (remember, they have to be fully qualified names as per the java Class documentation). This could include setting vals on the form or somewhere in the query generation - but it's pretty easy to specify that as I've shown. Granted, if you have a large number of tables to query across, then the above code is prob not the best approach. It could, though, maybe point you in the right direction.

Hope this helps,

- Jason


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 24, 2005 12:00 pm 
Newbie

Joined: Mon Apr 18, 2005 11:52 am
Posts: 5
j_l,

Thanks a lot for such detail and informative response. I will look into this and will get back to you with questions, if any. I appreciate your time for typing such long response.

Thanks,


Top
 Profile  
 
 Post subject: Free text searching
PostPosted: Tue Nov 08, 2005 11:21 am 
Newbie

Joined: Mon Nov 01, 2004 10:14 am
Posts: 2
Location: Sheffield, UK
Hiya...

I'm also very intersted in this thread, particularly the relationship between database specific indexing technologies and stand alone ones such as Lucene and similar engines. Basically, I would like to be able to use a free text operator as a part of HQL that maps correctly into MySQL match, Oracle Contains, the PostgreSQL free text seach, or perhaps even, a hibermate implemented inverted text index structure for those databases that don't have their own text indexing. I appreciate the proposal to use Lucene, but one of the reasons we use relational databases is that we need to do more traditional searching (And sometimes more contemporary searching such as spatial operators or large binary indexes). I guess for me it's a question of right tool for the job. I've got a big relational storage engine and I want to use it's features without introducing another technology. Many of the relational databases have their own text indexing engines,and it just seems like something that could be usefully abstracted out into the hibernate dialects?

Happy to help in any way possible to make this happen tho.

Ian.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.