You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »


Goals

  1. User can specified fields in nested object to be indexed. 

  2. Query on these nested fields as well as top level fields. 

 

Out of Scope

  1. Item in collection will not be index and searched.

 

API

  • Add a new method to create a lucene index that takes a callback. The callback gives the user explicit control of how their value is converted to lucene documents and stored in the index. 
/**
 * Create a lucene index using default analyzer.
 * @param luceneSerializer A callback which converts a region value to a 
 * Lucene document or documents to be stored in the index.
 */
public void createIndex(String indexName, String regionPath, LuceneSerializer luceneSerializer);

 
 
 
/**
 * An interface for writing the fields of an object into a lucene document
 * The region key will be added as a field to the returned documents.
 */
public interface LuceneSerializer {

  Collection<Document> toDocuments(Object value);
}


  • Use fieldnameAtLevel1.fieldnameAtLevel2 to specify a field in nested object both for indexing and querying. 

For example, a Customer object contains a Person field. A Person object contains a Page field.

public class Customer implements Serializable {
  private String name;
  private Person contact; // search nested object 
  ......
}
public class Person implements Serializable {
  private String name;
  private String email;
  private int revenue;
  private String address;
  private Page homepage;
  .......
}
public class Page implements Serializable {
  private int id; // search integer in int format
  private String title;
  private String content;
  ......
}

 

Following example demos how to index on nested fields: contact.name, contact.email, contact.address, contact.homepage.title. Note: each segment is a field name, not field type, because Customer class could have 2 Person fields: Person contact and Person deliveryman. Use field name is to identify the parent field.

 

// Get LuceneService
LuceneService luceneService = LuceneServiceProvider.get(cache);

// Create Index on fields, some are fields in nested objects:
luceneService.createIndexFactory().setLuceneSerializer(new FlatformatSeralizer()) /* an out-of-box LuceneSerializer implementation */
      .addField("name").addField("contact.name").addField("contact.email").addField("contact.address").addField("contact.homepage.title")
      .create("customerIndex", "Customer");

// Now to create region
Region CustomerRegion = ((Cache)cache).createRegionFactory(shortcut).create("Customer");


In query, the syntax for the nested field is the same as top level field, but to use qualified name as the field name, such as "contact.name:tzhou11*", otherwise, it's hard to distinguish which "name" field, because in flatformat, all the fields (including nested fields) are in one document. There're 2 "name" field. We have to specify querying on which "name" field. 

LuceneQuery query = luceneService.createLuceneQueryFactory().create("customerIndex", "Customer", "contact.name:tzhou11*", "name");
 
PageableLuceneQueryResults<K,Object> results = query.findPages();

Out-Of-Box implementation

We'll provide an out-of-box implementation for the LuceneSerializer: FlatformatSerializer.

It will still create one document for each parent object. But add the nest object as embeded fields of the document. The field name will use the qualified name. 

For example, the FlatformatSerializer will convert a Customer object into a document as

(name:John11),(contact.name:tzhou11), (contact.email:tzhou11@gmail.com), (contact.address:15220 Wall St), (contact.homepage.id:11), (contact.homepage.title: Mr. tzhou11), (contact.homepage.content: xxx)

 

  • No labels