Jackrabbit search
By default Magnolia’s search functionality is provided by the Jackrabbit repository and this page describes the configuration options for Jackrabbit-based search. For more advanced search options and especially if you need to manage high volumes of assets you can set up Magnolia to use Apache Solr, see Solr search.
How search indexing works
A workspace needs to be indexed in order to make information retrieval fast and accurate. Indexing is the process of collecting and parsing content, and storing the data in an index to make it easier and faster to retrieve requested portions of the data.
Magnolia search is based on the default Jackrabbit search implementation. Jackrabbit uses an Apache Lucene-based indexer to process the data stored in the JCR. Node names and property values are indexed immediately and stored in the repository. Text from documents is extracted in a background process which makes document content searchable after a short delay.
Each Magnolia instance has its own repository and its own index. This means that the author instance index is typically different from public instance indexes. Any content that has not been published to a public instance cannot be found when running a search on that public instance.
Apache Lucene Indexing Configuration
The Apache Lucene Indexing Configuration lets you specify indexed node properties, assess their impact on search results, and configure analyzers. The index configuration file defines how Lucene indexes a workspace. If a search indexing inconsistency occurs, it might be necessary to recreate the search index.
Implementing search using templating functions
Templating functions are used to render search results on a site without the need for a component model or Java knowledge. Although they are not directly related to the indexing process, you can use them to display the search results retrieved from the index.
There are many ways to implement search on a site.
This section explains how to do it using templating functions and uses the Magnolia Travel Demo site as an example.
If the demo modules are not installed your can download the magnolia-travel-demo-parent module
and install the demo and tours modules.
The MTE module provides search templating functions that allow front-end developers to render search results using only a template script.
Template function methods
There are methods for searching pages and other content, such as content stored in content apps.
The methods are exposed in templates as searchfn
and you can find templating examples at searchfn.
All you need to implement search on a site is a component to retrieve the results from the search index and display them on the page.
This is how search works on the Magnolia Travel Demo site.
-
searchResults
component searches pages and content apps for relevant results andsearchResults.ftl
renders this component. -
searchResultsPage
template autogenerates thesearchResults
component. -
Search results display on the
/travel/meta/search-results
page that is based on thesearchResultsPage
template. -
/search-results
page is assigned as the search page for the site in thehomePageProperties
dialog
See the travel-demo repository for specific examples. |
Displaying pages in the website workspace
The searchPages
method
displays pages stored in the website
workspace in the search results.
This method retrieves pages whose content (text, image and other
properties) was added manually in the
Pages app, as opposed to content
retrieved from an app or another source. Set the root path of the site
to return the relevant items.
Here’s the snippet from searchResults.ftl
in the Travel Demo. The root
path is /travel
.
[#-------------- ASSIGNMENTS --------------] [#assign queryStr = ctx.getParameter('queryStr')!?html] [#-------------- RENDERING --------------] [#if content.headline?has_content] <h2>${content.headline}</h2> [/#if] [#if queryStr?has_content] [#assign searchResults = searchfn.searchPages(queryStr, '/travel') /] [#assign recordsFound = searchResults?size /] <h3><em>${recordsFound}</em> ${i18n['search.pagesFoundFor']} "${queryStr}"</span></h3> <div class="list-group"> [#if searchResults?has_content] [#list searchResults as item] <a href="${cmsfn.link(item)}" class="list-group-item"> <h4 class="list-group-item-heading">${item.title!}</h4> <p class="list-group-item-text">${item.excerpt!}</p> </a> [/#list] [/#if] </div> <#-- More processing here, not shown in snippet > [/#if]
Here are the results for the term contact
.
Excerpts and
highlighting are provided automatically by the
indexing configuration.
Displaying content stored in apps
The searchContent
method
allows you to search any content in the JCR. The method is useful to
display pages
whose content is stored in another workspace. In this
scenario you need to set the
workspace where the
content is stored, the parent URL within that workspace and the
node type.
In the Magnolia Travel Demo site all Tour content (text, images and
more) is entered in the Tours app and retrieved by a component that
displays the content on pages. The app content is stored in the tours
workspace, under /magnolia-travels
and is of node type mgnl:content
.
Here’s the snippet from searchResults.ftl
that retrieves Tours app
content.
[#assign searchResults = searchfn.searchContent('tours', queryStr, '/magnolia-travels', 'mgnl:content') /] [#assign recordsFound = searchResults?size /] <h3><em>${recordsFound}</em> ${i18n['search.toursFoundFor']} "${queryStr}"</span></h3> <div class="list-group"> [#if searchResults?has_content] [#list searchResults as item] <a href="${cmsfn.link(item)}" class="list-group-item"> <h4 class="list-group-item-heading">${item.description!}</h4> <img src="${damfn.getAssetLink(item.image)}" class="img-responsive img-rounded" height="80" width="160" alt="${item.description!}"/> <p class="list-group-item-text">${item.excerpt!}</p> </a> [/#list] [/#if] </div>
Here are the results for the term swiss
.
URI mappings
You can use URI mappings to redirect incoming requests to the location of content, ensuring that the content is included in the search index. This means that URI mappings play a role in determining which content is indexed and how it is indexed in the search configuration.
When you display results from content app workspaces, build a link to a detail page that displays the content item in question using URI mappings. URI mapping is used in the Demo Travels example to display app content on pages and ensure that the content is included in the search index. |
Configuring URI2Repository mapping
The URI2Repository mapping URI mapping mechanism determines which repository node should be served when a particular URI is requested.
Here’s the URI2Repository mapping for the tours
workspace in
/server/URI2RepositoryMapping/mappings/tours
.
Property | Description |
---|---|
|
|
|
Injects the |
|
Repository the mapping applies to. |
Configuring VirtualURI mapping
Virtual URI mapping allows you to create short, convenient URLs.
Here’s the virtual URI mapping for the Tours app in
/modules/tours/virtualURIMapping/toursMapping
.
Property | Description | ||
---|---|---|---|
|
Tours virtual URI mapping node.
|
||
|
|
||
|
Path to tours in the tours workspace as mapped in the |
||
|
URI to which tours are forwarded |
Customizing search
You can customize search by writing your own queries to search the index and execute them in code. A query returns a result set which you can display on a page.
You can test your queries in the Query subapp. When you get the result set you want, implement the query in code.
Example queries
The following queries are written in SQL-2. See JCR Query Cheat Sheet for more examples.
-
Find pages that contain the word
swiss
.
Workspace: website
SELECT * FROM [mgnl:page] AS t WHERE
ISDESCENDANTNODE([/tours]) AND
CONTAINS(t.*, 'swiss')
-
Find modules that have commands. This query looks for a folder named
commands
in the module configuration.
Workspace: config
SELECT * FROM [mgnl:content] AS t WHERE
ISDESCENDANTNODE([/modules]) AND
name(t) = 'commands'
-
Find assets that are not JPG images under the
/example
path in the DAM.
Workspace: dam
SELECT * FROM [nt:base] AS t WHERE
([jcr:primaryType] = 'mgnl:asset' AND
[type] <> 'jpg') AND
ISDESCENDANTNODE([/example])
ORDER BY [t].title asc
Security
Search within Magnolia is access controlled. Search results include only content the user has permission to access. Permissions are controlled through Security. When you execute a query in info.magnolia.context.MgnlContext, contextual factors such as the current user’s permissions are taken into account. If you do not have permission to the items you are querying, they will not show up in the results.