Simplifying Lucene using Adapter Pattern , Generics , Reflection and Custom Attributes
Download : LuceneCloudAdapter.zip
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
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
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.