Example use case:

An Item may have multiple Labels assigned by Users. Each Label is a label attached to an Item by a single User.

entity Item {
 name : String (searchable)
 labels -> List<Label> (searchable)

entity Label {
 name : String (searchable)
 user -> User (searchable)

Now, on the item search page, we want to display the labels of the found items that are assigned by the User that is currently on the item search page.

We won't be able retrieve these user-tailored labels from the searcher used to find the items on the search page. We can only retrieve all labels assigned to the items in the search results (by using faceting on the field labels.name)

For this to work efficiently, we need to have dynamic fields, i.e. fields that are created at runtime. If we create a dynamic search field, uniquely named for each User appearing in the list of labels of an item, we will be able to retrieve only the label names of items that are given by a specific user.

Proposed Solution:

We can introduce an overridable entity function, with signature getDynamicSearchFields() : Set<DynamicSearchField>.

When overridden, this function will be used to add the DynamicSearchFields to the indexed document representation of an entity.

A DynamicSearchField will hold 2 values, namely the name of the search field and the value to be indexed untokenized, that is: no analysis will be performed on the value to be indexed.

For now, any normalization of the text should be done in the body of the getDynamicSearchFields-function.

For the example above, we would extend the Item entity as follows:

extend entity Item{
  function getDynamicSearchFields() : Set<DynamicSearchField> {
    var toReturn := Set<DynamicSearchField>();
    var fld : String;
    var val : String;
    for ( l : Label in this.labels ) {
      fld := l.user.name + "-label";
      val := l.name;
      toReturn.add( DynamicSearchField( fld ,val) );

    return toReturn;

Now, on the search page, we can enable faceting on the search field "$username$-label" and show the names of labels assigned by the currently visiting user.

Submitted by Elmer van Chastelet on 19 December 2012 at 13:41

On 19 December 2012 at 13:41 Elmer van Chastelet tagged search

On 7 January 2013 at 15:06 Elmer van Chastelet commented:

This has been added and tested locally in r5580.
Web-test has been added in r5581.

On 7 January 2013 at 15:44 Elmer van Chastelet closed this issue.

On 7 January 2013 at 18:52 Elmer van Chastelet tagged 1.3.0

On 9 January 2013 at 14:49 Elmer van Chastelet reopened this issue.

On 9 January 2013 at 14:54 Elmer van Chastelet commented:

I've reopened this issue, because queries performed on a dynamic field should not be analyzed (as they are indexed untokenized). The PerFieldAnalyzerWrapper of Hibernate falls back to the default analyzer in case of an unmapped search field, which dynamic search fields are.

This is also related to the use of untokenized fields in general: whitespaces will be treated as token seperator by the MultiFieldQueryParser. We need to treat untokenized and dynamic fields differently.

On 18 January 2013 at 12:29 Elmer van Chastelet commented:

Also need to think about the facet index readers of bobo-browse, which we currently renew whenever a new (unhandled) faceting field is encountered. If an increased number of fields put in the facet handlers has negative impact on performance/resource, it might become problematic.

On 11 June 2013 at 10:21 Elmer van Chastelet removed tag 1.3.0

On 11 June 2013 at 10:21 Elmer van Chastelet tagged 1.4.0

Log in to post comments