My favorites | Sign in
Project Logo
                
Search
for
Updated Oct 28, 2009 by chas66
Labels: Featured
CompassSearching  

Searching in Appfuse 2.0.2 with Compass 2.0 and Lucene 2.3.2

There are a few of tutorials for getting Compass (and therefore Lucene) to work with Appfuse around; however with the advent of Compass 2.0 release, I thought I'd update and give a working example.

Compass 2.0 has a lot of nice features, including annotations, default AND of query terms (used to be OR), and built in result paging.

This example project also shows the use of the Compass built in paging, and also 'external' paging via Displaytag.

See Also

More complex searching - multiple models: http://code.google.com/p/pagingappfuse/wiki/MoreCompassSearching

Projects

Code

This extends the external PagingSorting example, all the source code is available as a SVN branch. see instructions here : http://code.google.com/p/pagingappfuse/source/checkout you want to checkout the branches/search tree (the trunk has the PagingSorting code only ) e.g.: https://pagingappfuse.googlecode.com/svn/branches/search/ or you can browse the source at: http://code.google.com/p/pagingappfuse/source/browse in the branches/search subdirectory

Changes to the previous external PagingSorting project are as follows:

STEPS

1) edit pom.xml and add a new repository (it's not in the main repo yet see http://forum.compass-project.org/thread.jspa?messageID=294522&tstart=0 ):

        <repository>
            <id>compass</id>
            <url>http://repo.compass-project.org</url>
        </repository>

2) edit the pom.xml and add in the new dependencies:

  <dependency>
            <groupId>org.compass-project</groupId>
            <artifactId>compass</artifactId>
            <version>${compass.version}</version>
        </dependency>
     <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-core</artifactId> 
          <version>${lucene.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-analyzers</artifactId> 
          <version>${lucene.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-highlighter</artifactId> 
          <version>${lucene.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-queries</artifactId> 
          <version>${lucene.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.lucene</groupId>
          <artifactId>lucene-snowball</artifactId> 
          <version>${lucene.version}</version>
      </dependency>

3) add new properties to the foot of your pom.xml:

        <!-- Compass Settings -->
        <compass.version>2.0.0</compass.version>
        <lucene.version>2.3.2</lucene.version>

4) Add annotations to your model - have a look at Authority.java, the annotations available to you are documented here http://www.compass-project.org/docs/2.0.0/reference/html/core-osem.html

5) Add a reindex.jsp and a search.jsp

6) Add a new controller CompassSearchController.java - this is almost the same as that supplied with Compass, however in the handle method there are a couple of extra lines that decode DisplayTag's page request and set it into the Command, if you are not using DisplayTag then just reuse the CompassSearchController that comes with Compass itself.

7) Add the compass beans to applicationContext.xml - these wire up Compass to Hibernate using the new Compass HibernateGpsDevice so that the index will be updated when Hibernate commits data to the RDBMS. This is also where you declare your annotated class to compass. Note that a number of non-default properties are set on the Compass bean - for instance the use of the Snowball analyzer (for English).

8) URLMappings - add search and reindex to the URLMapping - mapping them to their respective controllers: see dispatcher-servlet.xml

  /search.html=searchController
  /reindex.html=indexController

9) add in beans for the new controllers (see dispatcher-servlet.xml ):

    <!-- ====  COMPASS SEARCH CONTROLLER ==== -->
    <bean id="searchController" class="com.pobox.paging.webapp.controller.SearchController">
        <property name="compass"><ref bean="compass"/></property>
        <property name="searchView"><value>search</value></property>
        <property name="searchResultsView"><value>search</value></property>
        <property name="pageSize"><value>25</value></property>
    </bean> 

    <bean id="indexController" class="org.compass.spring.web.mvc.CompassIndexController">
        <property name="compassGps"><ref bean="compassGps"/></property>
        <property name="indexView"><value>reindex</value></property>
        <property name="indexResultsView"><value>reindex</value></property>
    </bean>

10) Add search to the main menu, and reindex to the admin menu : menu-config.xml and menu.jsp

11) fire it up with mvn jetty:run-war , log in as admin and select re-index from the main menu - build the index (it's in ${user.home}/compass if you wish to browse it with Luke)

12) try a search for the term 2008* it should find all 106 records, (matching on the version date year), showing only the first 25.

13) The search page is a hybrid - raw HTML at the bottom (with paging courtesy of Compass), and Displaytag at the top (sorting is disabled - but you could add this functionality in). Displaytag is doing external sorting and paging correctly, however the header says "Displaying 1-25" regardless of what page you are on - this is a Displaytag bug I think :

Further Improvement?

1) Sorting - sort search results; a CompassQuery can be sorted eg: compassQuery.addSort("propertyName",SortPropertyType.STRING, SortDirection.REVERSE);

2) Fix DisplayTag bug "Display 1 to 25" by implementing a PaginatedList instead


Comment by alex.coles, May 23, 2008

Great work on this! This is really useful - I got to the same point as you through my own work some months ago, but wish I had this tutorial around then!

A quick note - you can make your syntax even more concise in your dispatcher-servlet.xml as follows:

    <bean id="searchController" class="com.pobox.paging.webapp.controller.SearchController">
        <property name="compass" ref="compass"/>
        <property name="searchView" value="search"/>
        <property name="searchResultsView" value="search"/>
        <property name="pageSize" value="25"/>
    </bean>
    
    <bean id="indexController"
    class="org.compass.spring.web.mvc.CompassIndexController">
        <property name="compassGps" ref="compassGps"/>
        <property name="indexView" value="admin/indexItems"/>
        <property name="indexResultsView" value="admin/indexItems"/>
    </bean>
Comment by WeaponOfPackDestruction, Aug 07, 2008

Thanks for the example!

I have a couple of small suggestions. First, the HTML in your reindex.jsp and search.jsp files is neither HTML 4.0 nor XHTML compliant. I could paste in my fixed up version later (as soon as I fix them up :-) ). Second, could you expand a little bit on the relationship between the compass annotations on Authority.java and the property names used in search.jsp? Are those property names (e.g. row.data.authorityName) related to the @SearchableProperty? name attribute or the @SearchableMetaData? name attribute?

Thanks!

Comment by shinjix, Aug 26, 2008

There are a bug in the text. When it says

"Add a new controller CompassSearchController?.java"
It must be
"Add a new controller SearchController?.java"
no?

Comment by dunmakemethink, Sep 22, 2008

I got a error when I following this tutorial, as below, is there any thing I missed? ERROR main? DispatcherServlet?.initServletBean(290) | Context initialization failed

74 org.springframework.beans.factory.BeanCreationException?: Error creating bean with name 'authorityFormController' defined in ServletContext? resource [/WEB-INF/dispatcher-serv 75 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory?.doCreateBean(AbstractAutowireCapableBeanFactory?.java:478)

Comment by jones.tate, Apr 21, 2009

Tried following instructions with compass 2.2.0 and Lucene 2.4.1 without success. Had to remove the SpringSyncTransactionGpsDeviceWrapper?. No errors reported in the logs, however the Lucene index is empty. Any reported issues?

Comment by chas66, Jun 17, 2009

http://svn.compass-project.org/svn/compass/branches/2_2/upgrade.txt says that in that version (2.2.0) SpringSyncTransactionGpsDeviceWrapper? is not required and was removed

Comment by dashaun, Jun 18, 2009

How can we provide search across multiple models? Say Authority and User?

Comment by chas66, Oct 28, 2009

Search across multiple models can be seen here: http://code.google.com/p/pagingappfuse/wiki/MoreCompassSearching


Sign in to add a comment
Hosted by Google Code