Last updated by mauk81 1 year ago

Compass concepts

Properties of your domain classes will be mapped with one of the following strategies:

Searchable Property

This is used for simple types (or collections of), basically anything that can be represented as a string in the index, eg, strings, numbers, dates, enums, etc.

We might use the phrase "searchable property" to refer to the class property that is mapped as a searchable property, as well as the mapping concept.

Within the index, a Lucene field named after the property is created, and the value of that field contains the searchable text. You can then target that field with a prefixed term in the query.

Additionally Compass creates a field in the index called "all" which contains all searchable text for a class instance. If you do not prefix search query terms, they hit the "all" field.

You can and probably should map your own immutable/value-types as searchable-properties.

You can provide a custom Converter implementation to convert the object to/from String form.

Example

Given the following class:

class Book {
    String title, text
}

title and text can be mapped as a searchable-properties.

You can then search specifically for text in title with a query string like "title:attack" .

The query string "attack" would match Book s with that word in their title or text fields (or both), because in fact it hits the "all" field which combines all searchable text for the class instance.

Searchable Reference

This is used for complex types (or collections of); typically associated domain classes.

We might use the phrase "searchable reference" to refer to the class property that is mapped as a searchable reference, as well as the mapping concept.

A searchable-reference's class must be searchable itself.

When indexing an object its searchable-references are stored in their own indexes (Compass calls these "sub-indexes").

The relationship is also stored in the index belonging to the class with the searchable reference mapping. This is simply the class type and id of the other object(s), so it's efficient.

Therefore:

  1. Objects on either side of the relationship are first-class citizens in the index and can be search for in their own right.
  2. When searching, hits will only occur for text present within the searchable class instance itself
  3. When re-creating an object from the index (for search results), Compass can re-create its relationships too.

Example

Given the following two classes

class Post {
    Set<Comment> comments
    // ..
}

class Comment {
    Post post
    // ....
}

lets says both classes are searchable and both Post#comments and Comment#post are mapped as searchable-references .

Now when a search matches a Post then the Post will be returned from the index with the comments populated from data saved in the index - it doesn't hit the database.

Likewise if a search finds a Comment it can be returned along with it's associated Post .

Searchable Component

This is used for complex types (or collections of); typically associated domain classes.

We might use the phrase "searchable component" to refer to the class property that is mapped as a searchable component, as well as the mapping concept.

A searchable-component's class must be searchable itself.

Unlike searchable-references, when indexing searchable-components, those searchable-component objects are not stored in their own indexes (at least from the owning side). Instead the data of the searchable-component is stored within the owning object's own searchable data. In other words, the searchable data of a searchable-component is added to the searchable data of the class instance declaring the property.

Therefore:

  1. You can search for data that is embedded into a top-level object from a searchable component, this counts as a match for the top-level object
  2. If the searchable component's class is not mapped as a root class, then you will never find instances with search
  3. When re-creating an object from the index (for search results), Compass can re-create its associated searchable-components too.

Example

Given the following two classes

class Post {
    Set<Comment> comments
    // ..
}

class Comment {
    Post post
    // ....
}

lets says both classes are searchable and both Post#comments and Comment#post are mapped as searchable-components .

Now the user searches for a string that happens to match a Comment , they will get both Post and Comment hits. Additionally search result objects will have their associations populated, and this doesn't hit the database.

More on Searchable Reference and Searchable Component

You cannot map the same class property as both a searchable reference and a searchable component.

However if you have a bidirectional relationship, it is possible to map one side of a relationship as a searchable-reference and the other as searchable-component.