XAP

Free Text Search

Free text search is required almost with every application. Users placing some free text into a form and later the system allows users to search for records that includes one or more words within a free text field. A simple way to enable such a search without using a regular expression query that my have some overhead can be done by using an array or a collection of String.

Example

Our SpaceClosed Where GigaSpaces data is stored. It is the logical cache that holds data objects in memory and might also hold them in layered in tiering. Data is hosted from multiple SoRs, consolidated as a unified data model. class includes the following - note the words and the freeText fields:

public class MyData {


    private String[] Words {set; get;}

    private String FreeText{set; get;}

    public String[] GetWords() {
        return Words;
    }

    public void SetWords(String[] ws) {
        this.Words=ws;
    }

    public String getFreeText() {
        return FreeText;
    }

    public void setFreeText(String freeText) {
        this.FreeText = freeText;
        this.Words = FreeText.Split(" ");
    }
}

Note how the freeText field is broken into the words array before placed into the indexed field.

You may write the data into the space using the following:

MyData data = new MyData(...);
data.FreeText(freetext);
proxy.Write(data);

You can query for objects having the word hello as part of the freeText field using the following:

MyData results[] = proxy.ReadMultiple<MyData>(new SqlQuery<MyData>("Words[*]='hello'"));

You can also execute the following to search for object having the within the freeText field the word hello or everyone:

MyData results[] = proxy.ReadMultiple(new SqlQuery<MyData>("Words[*]='hello' OR Words[*]='everyone')");

With the above approach you avoid the overhead with regular expression queries.

Indexing

To speed up the query you can create an index on the fields you want to search.

public class MyData {

    [@SpaceIndex (path="[*]")]
    private String[] Words {set; get;}

    private String FreeText{set; get;}

    public String[] GetWords() {
        return Words;
    }

    public void SetWords(String[] ws) {
        this.Words=ws;
    }

    public String getFreeText() {
        return FreeText;
    }

    public void setFreeText(String freeText) {
        this.FreeText = freeText;
        this.Words = FreeText.Split(" ");
    }
}

The same approach can be implemented also with the SpaceDocument.

Regular Expressions

You can query the space using the SQL like operator or Java Regular Expression Query syntax.

When using the SQL like operator you may use the following: % - match any string of any length (including zero length) _ - match on a single character

SqlQuery<MyClass> query = new SqlQuery<MyClass>("Name like 'A%'")

Querying the space using the Java Regular Expression provides more options than the SQL like operator. The Query syntax is done using the rlike operator:

// Match all entries of type MyClass that have a name that starts with a or c:
SqlQuery<MyClass> query = new SqlQuery<MyClass>("Name rlike '(a|c).*'");

All the supported methods and options above are relevant also for using rlike with SqlQuery.

Case Insensitive Query

Implementing case insensitive queries can be done via:

  • like operator or rlike operator. Relatively slow. Not recommended when having large amount of objects.
  • Store the data in lower case and query on via lower case String value (or upper case)