Simplifying Lucene using Adapter Pattern , Generics , Reflection and Custom Attributes

 

Today is a special day 12-12-2012 , so I tried really to release something I really want to do

from long time.

 

I am introducing a draft Idea of how we can make Lucene.Net more RAD and also simplifying

how the .Net Developers will interact with Lucene.Net .

 

The Idea is very simple we need to make the developer code normally in C# Generics

that mean the developer just need to build a List of his document object List<Student>

for example , and passing this to Lucene.Net to store it using default Index and Store configuration

also to search Lucene.Net either send a free string search query , or build a search object that

really represent your criteria to search your document.

 

by building an Adapter component that will handle the communication between Lucene.Net

and C# Objects using very simple calls that will allow the result of the Idea to come to true

 

using custom Attributes to allow us to decorate the Document class properties

to explicit say what type of Index or Store you want this property to be configured in Lucene.Net

 

Lucene

 

 

I attached a complete working examples that describe the Idea , please feel free to try it

and add your comment of how we can extend this

 

search

 

this how the code will look like for Pushing Data to cloud :

// see now how easy we will store the data in correct lucene format
// 2 lines of code and full OOP
List<Student> Students = GetStudentsFromDB();
LuceneCloudAdapter<Student, SearchStudents> lcA = 
    new LuceneCloudAdapter<Student,SearchStudents>(DocContext);
bool result=lcA.PushToCloud(Students);

 

this is how the code will look like for searching data using search string:

LuceneSearchInfo si = new LuceneSearchInfo();
string searchStr = "Name:Haitham";
List<Student> Students = lcA.Search<Release>(searchStr, true, si);

this is how the code will look like for searching data using search Object :

 

//fill the search object with data
SearchStudents se = new SearchStudents();
//.... fill your search object here
// .....

// no we had filled the search object simply you will pass it for search function.
LuceneCloudAdapter<Student, SearchStudents> lcA = 
       new LuceneCloudAdapter<Student, SearchStudents>(DocContext);
LuceneSearchInfo si = new LuceneSearchInfo();
List<Student> Students = lcA.Search<Student>(se,si);

 

 

A document class will look like this you can remove custom attributes if you want to use the default :
class Student
{
  [LuceneIndex(Value = IndexAttribute.NOT_ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public int id { get; set; }

  [LuceneIndex(Value = IndexAttribute.ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public string name { get; set; }

  [LuceneIndex(Value = IndexAttribute.ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public string department { get; set; }

  [LuceneIndex(Value = IndexAttribute.NOT_ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public DateTime startdate { get; set; }

  [LuceneIndex(Value = IndexAttribute.NOT_ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public float gpa { get; set; }

  [LuceneIndex(Value = IndexAttribute.NOT_ANALYZED)]
  [LuceneStore(Value = StoreAttribute.YES)]
  public double allowance { get; set; }
}

 

A search class will look like this :

class SearchStudents
{
 // this is the same as the object class 
 // If you will search the field normally add the same field name
 //if you will search the field in range , add from , and to to the field.
 
 public int? id { get; set; }
  
 public string name { get; set; }
  
 public string department { get; set; }

 //range search for Start Date and other ranges

 public DateTime? startdatefrom { get; set; }
  
 public DateTime? startdateto { get; set; }
  
 public float? gpafrom { get; set; }

 public float? gpato { get; set; }
  
 public double? allowancefrom { get; set; }
  
 public double? allowanceto { get; set; }
}
 
please see the attached project sample and everything will be very clear.
 
Conclusion :

the Idea behind that class that it is used as an Adapter Pattern to simplify the communication between Lucene.Net and C# OOP so developers can send normal object to search and also receive the result in a collection using Reflection and custom attributes to simplify Lucene and make it more RAD development
the next step really is to componentize this to make it a visual component that can communicate with DB providers like SQL server , and generate classes and search UI by drag drop , like the DataSet component and other Data Sources components.

11 Comments

Comments have been disabled for this content.