Thursday, December 21, 2006

Hibernate Lucene Search

ผมมี Idea เรื่องที่จะใช้ Lucene ทำ search index
ของ Domain model มานานแล้ว
แต่ก็ไม่ได้โอกาสทำเสียที
มาตอนนี้ Hibernate 3.2 เขาทำ feature นี้ออกมาให้ใช้เรียบร้อยแล้ว
แถม integrate ได้เนียนดีด้วย

ลองดูตัวอย่างการใช้งาน

ขั้นแรกสุด ก็คือ "การระบุว่า domain ไหนที่ต้องการทำ index"
ตรงนี้เขาใช้ annotation Indexed เข้ามาช่วย
@Indexed(index="indexes/people")
@Entity
public class Person {
...
}

lucene มองสิ่งที่ถูก index ว่าเป็น document
ดังนั้นก็เลยต้องมีการระบุ tag DocumentId
ไว้ที่ primary key ด้วย
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@DocumentId
public Long getId() {
return id;
}

field ไหนที่ต้องการทำ index ก็ต้องระบุด้วย tag Field
@Field(index=Index.UN_TOKENISED)
public String getName() {
return name;
}


เพื่อให้ lucene ทำ index โดยอัตโนมัติ หลังจากที่เรา hibernate insert,update หรือ delete
เราก็ต้อง config add listenter เข้าไป
<event type="post-update">
<listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
</event>

<event type="post-insert">
<listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
</event>

<event type="post-delete">
<listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
</event>


การ config ระบุว่าจะเก็บ index file ที่ไหน ทำผ่าน directory_provider
hibernate.search.default.directory_provider org.hibernate.search.store.FSDirectoryProvider
hibernate.search.default.indexDir=/usr/lucene/indexes


ส่วนการสืบค้นข้อมูล จะเห็นว่าเขาพยายามดึงให้เข้าไปใช้ org.hibernate.Query
ลองดูตัวอย่าง
Session session = HibernateUtil.getSession();
FullTextSession fullTextSession = Search.createFullTextSession(session);
QueryParser parser = new QueryParser("title", new StopAnalyzer());
org.apache.lucene.search.Query query = parser.parse("name:bunn");
org.hibernate.Query query2 = fullTextSession.createFullTextQuery(query);
List results = query2.list();

for (Person tmp : results) {
System.out.println("id =" + tmp.getId() + ",name = " + tmp.getName());
}

Related link from Roti

No comments: