Find All Documents That Link to a Specific Document

Overview

This page describes how to create and execute a search query to find all documents that contain a link to a specific document in Bloomreach Content.

When to Use

Use this approach when you need to retrieve all documents that reference a particular document. A common scenario is displaying all comments associated with an article, where each comment is a separate document linked to the article.

Technical Background

In Bloomreach Content, you create relationships between documents by linking them. At the content repository level, these links are represented by nodes of type hippo:mirror or hippo:facetselect (or their subtypes).

For example, to relate a comment to an article, the comment document includes a child node of type hippo:mirror. The hippo:docbase property of this node stores the UUID of the handle node of the target document.

The following structure illustrates this relationship:

/content: /documents: /news: /2012: /my-news-article: jcr:primaryType: hippo:handle jcr:uuid: xxxx-xxxx-xxxx-xxxx /my-news-article: jcr:primaryType: hippo:document /comments: /2012: /my-news-article: jcr:primaryType: hippostd:folder /comment-1: /hippo:mirror: hippo:docbase: xxxx-xxxx-xxxx-xxxx /comment-2: /hippo:mirror: hippo:docbase: xxxx-xxxx-xxxx-xxxx

In this example:

  • The my-news-article document has a handle node with UUID xxxx-xxxx-xxxx-xxxx.
  • Two comments (comment-1 and comment-2) each have a hippo:mirror child node with a hippo:docbase property referencing the article's UUID.
  • This structure allows you to query for all comments linked to my-news-article by searching for documents with a hippo:mirror node whose hippo:docbase matches the article's UUID.

The HST API provides the ContentBeanUtils class, which includes methods such as createIncomingBeansQuery to simplify these queries.

Implementation

Example 1: Retrieve the 10 Most Recent Comments on a News Article

The following example demonstrates how to query for the 10 most recent comments linked to a news article.

@Override public void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException { final HstRequestContext context = request.getRequestContext(); // Expect a NewsDocument in a news detail component NewsDocument newsDocument = context.getContentBean(NewsDocument.class); if (newsDocument == null) { response.setStatus(HstResponse.SC_NOT_FOUND); return; } // Set the newsDocument on the request request.setAttribute("document", newsDocument); // Query for the 10 most recent comments try { // Create a HstQuery to find CommentBean documents that: // 1. Have a hippo:mirror link at 'example:commentlink' // 2. The link points to 'newsDocument' // 3. Are located below the site content base HstQuery commentsQuery = ContentBeanUtils.createIncomingBeansQuery( newsDocument, context.getSiteContentBaseBean(), "example:commentlink/@hippo:docbase", CommentBean.class, false); // Order by date descending commentsQuery.addOrderByDescending("example:date"); // Limit to 10 results commentsQuery.setLimit(10); // Execute the query and add the result to the request HstQueryResult comments = commentsQuery.execute(); request.setAttribute("comments", comments); } catch (QueryException e) { log.warn("QueryException ", e); } }

To render the comments, iterate over the results using a HippoBeanIterator from HstQueryResult#getHippoBeans().

Example 2: Add Constraints to the Comment Query

You can add additional constraints to the HstQuery returned by createIncomingBeansQuery using the Legacy Search API. Note that you cannot use the Fluent Search API for queries created this way.

The following example restricts the query to comments made in the last year and containing a specific search string:

@Override public void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException { final HstRequestContext context = request.getRequestContext(); // Expect a NewsDocument in a news detail component NewsDocument newsDocument = context.getContentBean(NewsDocument.class); if(newsDocument == null) { response.setStatus(HstResponse.SC_NOT_FOUND); return; } // Set the newsDocument on the request request.setAttribute("document", newsDocument); // Query for the 10 most recent comments try { // Create a HstQuery as in the previous example HstQuery commentsQuery = ContentBeanUtils.createIncomingBeansQuery( newsDocument, context.getSiteContentBaseBean(), "example:commentlink/@hippo:docbase", CommentBean.class, false); // Order by date descending commentsQuery.addOrderByDescending("example:date"); // Limit to 10 results commentsQuery.setLimit(10); Filter extraFilter = commentsQuery.createFilter(); // Filter for comments since last year Calendar sinceLastYear = Calendar.getInstance(); sinceLastYear.add(Calendar.YEAR, -1); extraFilter.addGreaterOrEqualThan("example:date", sinceLastYear); // Add a free text search constraint String query = SearchInputParsingUtils.parse(..., false); extraFilter.addContains(".", query); // Combine the extra filter with the main filter ((Filter) commentsQuery.getFilter()).addAndFilter(extraFilter); // Execute the query and add the result to the request HstQueryResult comments = commentsQuery.execute(); request.setAttribute("comments", comments); } catch (QueryException e) { log.warn("QueryException ", e); } }

Render the results as in the previous example using a HippoBeanIterator.

Broader Queries with Wildcards and Depth

If you do not know the exact path where links are stored in the documents, you can use wildcard link paths or specify a search depth. For example, to find all instances of HippoDocument that link to your document, regardless of the link's location, use one of the following approaches:

  • Specify wildcard paths such as "*/@hippo:docbase" or "*/*/@hippo:docbase".
  • Provide a list of possible link paths, for example: {"*/@hippo:docbase", "*/*/@hippo:docbase"}.
  • Use the depth parameter to automatically include all link paths up to the specified depth.

The following table shows the correspondence between depth and link paths:

DepthLink Paths
1{"*/@hippo:docbase"}
2{"/@hippo:docbase", "/*/@hippo:docbase"}
3{"/@hippo:docbase", "//@hippo:docbase", "///@hippo:docbase"}
4{"/@hippo:docbase", "//@hippo:docbase", "///@hippo:docbase", "////@hippo:docbase"}

To use depth in your query:

// Using depth = 2 finds incoming beans with links at "*/@hippo:docbase" or "*/*/@hippo:docbase" int depth = 2; HstQuery commentsQuery = ContentBeanUtils.createIncomingBeansQuery( newsDocument, context.getSiteContentBaseBean(), depth, HippoDocument.class, false);

Summary

To find all documents that link to a specific document, use the ContentBeanUtils.createIncomingBeansQuery method. Adjust the query parameters, constraints, and link paths as needed for your use case. Use search depth or wildcard paths when the link location varies.

Share Feedback
Page: /build/search/jcr-search/search-all-hippodocument-beans-that-have-a-link-to-a-hippodocument-you-have
Section: Build
Category *