Opentaps Search Feature
The basic idea is to use Hibernate Search to index data in the opentaps database, and then have a search tool which allows you to find results based on keywords rather than explicit parameters like on a find form. The overall architecture should support integration to external search interfaces such as Google Enterprise Search fairly easily.
Search is a form of data retrieval similar to SQL. To make it easy for you to switch one search service for another, we have created a search domain based on the Domain Driven Architecture. All basic search functionality is implemented in this domain, even though they may the searching other domains. In the search domain you would therefore find services for parties, accounts, contacts, leads, and suppliers as well as for quotes, sales opportunities, sales orders, and purchase orders.
Each application (CRM, purchasing, etc.) can then have its own search service which reuses best search components from the common search domain. For example CrmsfaSearchService will access the account, contact, lead, order, sales opportunity, etc. search services. It has method such as getAccounts(), getContacts(), getSalesOpportunities(), getSalesOrders() to return lists of entity objects. Purchasing initially will just have search of the suppliers and orders domain to getSuppliers() and getPurchaseOrders().
Implementing search this way makes it easier to replace one search technology with another. For example, one day we may have a document management domain in opentaps, and there could be a DocumentSearchServiceInterface in this domain. This interface might specify that for a set of keywords, it will return a List<Document> of Document objects which might have the names, summaries, and links to the actual documents. In one implementation, we might use the Google Search Appliance to implement the DocumentDomainSearchInterface, but in another instance, we could use a different document indexing and search tool. Applications such as CRM and purchasing could then call on the document domain to search for documents, while being separated from the actual implementation of the indexing and search.
The indexing of entities for search is configured by hot-deploy/opentaps-common/config/entitysearch.properties. You can configure an entity to be indexed:
SalesOpportunity = index
And you can also configure the weights of the entity's fields:
SalesOpportunity.salesOpportunityId = 1 SalesOpportunity.opportunityName = 10 SalesOpportunity.description = 1 SalesOpportunity.nextStep = 1
Sometimes you'll have to index entities such as SalesOpportunityRole or PartyRole, so that the search services can use them to determine the type of party and whether it is an account, contact, or lead.
Note that view entities can not be indexed, since they are not actually stored in the database.
Integration with Persistence Layer
Because we are using hibernate search, data stored with hibernate will automatically be indexed.
For data stored using the ofbiz entity engine, opentaps uses aspect oriented programming (AOP) to intercept the ofbiz delegator's Entity-Event-Condition-Action (EECA) sequence. Normally, after the delegator stores a value, it will evaluate EECA's attached to the entity to see if any services should be run. opentaps has added an aspect to the ofbiz delegator, so that it will also index the entity stored.
Displaying Search Results
The results of the search should be passed to our GWT EntityListViews so that the webapps could display them.
Clearing Search Indices
The hibernate search index files are located in runtime/lucene/indexes (this is defined in org.opentaps.domain.container.HibernateCfgGeneratorContainer.java) and can be cleared by
$ ant refresh
After clearing them, you will need to run the opentaps.createHibernateSearchIndex service again to re-build them.