Translate

Friday, April 3, 2015

Example 14: Searching Assets using Lucene Search API

Hello, this blog corresponds to the chapter - Public Site Search from Oracle WebCenter Sites developer's guide but also applies to FatWire 7.x version too.

Before jumping into example, one should know the architecture behind lucene search used in Sites/FatWire:

There are 2 types of indexes: Global and AssetType. Default attributes present in
1. Global indexes is defaultSearchField which contains all the following: asset type, asset subtype, name, description, status, createdby, updatedby, updateddate, startdate, enddate, fw_uid, id, fw_tags, all asset's flex attributes. Other attributes are also stored as stated in guide. All the indexes are stored under <WCS_Installed_Folder>/shared/lucene/Global
2. AssetType indexes - All the metadata in defaultSearchField and rest attributes in seperate columns as stated in guide. All the indexes are stored under <WCS_Installed_Folder>/shared/lucene/<AssetType>

This indexes can be checked via one tool - LUKE

You should check out this chapter in Admin Guide for configuring lucene indexes and once you know how to configure, you can proceed with coding to search assets via lucene search API.

When to use what?

Global indexes are used for searching against any asset types, hence, then name Global index and Public Site Search. You can search against multiple asset types given that there is a common attribute like name, description, createdby, etc. or even if you have created your flex family in such a way that all the asset types fall under one Attribute type and there is one common attribute among all the definition, that attribute can used for Global/Public site search.
AssetType indexes as you can guess is limited to only one Asset Type search.

Common methods and their description are provided in Guide here. You can also browse through javadoc to see various methods.

Example: The following example can be used to search against AVIArticle for AviSports site which comes along with JSK 11g. Enable AVIArticle lucene index and enable GLOBAL indexes for AVIArticle too. Add the attributes like headline, abstract, postDate, etc. for indexing. Once done, proceed with creation of one template - SearchLayout (type: Page and usage: can be used as Layout and add 2 params in cache-criteria - keyword and form-to-render) and just save. Create one Page asset with nothing in it, just a name should suffice, and assign this template SearchLayout. (You can also place this page under AviSports home page so that it will be visible in top navig)

Copy and paste code form Page/ArticleLayout.jsp to this template - SearchLayout. Delete the main container code from the template which would look like this:
This snippet was taken from HomeLayout template present in 11.1.1.6.0 JSK

Thus, now all the code will be under between container id.

First, just a simple form tag with one input field like text with name="keyword" (keyword search will be performed against headline or abstract field for AVIArticle asset). Replace the <form> tag into <satellite:form> tag (don't forget to include satellite tag lib at the top of your template).

Use the tag: <render:gettemplateurlparameters> to generate URL for this page itself (Same page will be called after the form is submitted) and render all the args name and value inside <satellite:form> as hidden params. Check the tag here.  (don't forget to include string tag lib at the top of your template). It should end up like this:

Once search form is completed, proceed with search lucene search logic as shown.


and then, just load the query and show the results as required:

































You can download the source code from here.

Update: In latest 11g version, you have the ability to configure vanity URLs per asset. So if you have vanity URL enabled, then the above search may not work. There are 2 or more possible solutions, I am listing 3 of them:
1. Apply Patch 2 or greater and replace <satellite:form> with <form> tag. Pass action url in form and remove passing of hidden params via <render:geturltemplateparameters> tag.
2. Another way is to delete vanity URL entry for the page asset. Go to your page asset, search for the URL tab, copy the URL and go to Admin UI -> System tools -> double click URL -> Select "URL" as search criteria, paste the URL which you copied and then search. Select the entry and click delete, this will remove vanity URL for the page asset. Check your search page asset, there should be no vanity URL in URL tab. Above code will work with this configuration.
3.  Don't pass action url, this way you get form but again no vanity url.

Notes:

1. If you want to build global site search, then following changes should be done. Note: There should be at least one common attribute to search against.

IndexSourceMetadata metadata = con.getConfiguration( "Global" );
QueryExpression typeQ = new QueryExpressionImpl(SearchIndexFields.Global.ASSET_TYPE, Operation.EQUALS, "AVIArticle");
typeQ = typeQ.or(SearchIndexFields.Global.ASSET_TYPE, Operation.EQUALS, "AVIImage");

2. If you want to search against Parent assets. For e.g. finding AVIArticles with parent "Skiiing", use filter: FieldCopier to copy parent id in one attribute and enable this attribute for indexing and update your query to search against that indexed attribute name.

3. Similar above steps can be done to search against associated content.


----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------