Lucene入门
1、Lucene简介
2、索引---Lucene如何建索引
IndexWriter==>写索引
Document ==>代表要索引文档
Field===》文档中的一个字段,一项数据
IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR), new StandardAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
writer.optimize();
writer.close();
public void createIndex() throws Exception{
//等待索引的内容文档
String s1="What is your name?";
String s2="My name is chengdu itcast!";
String s3="What is that?";
String s4="It is chengdu itcast, ChengDu ITCAST!";
//索引目录
Directory d=new SimpleFSDirectory(new File("f:/test/index"));
//分词器
Analyzer a=new SimpleAnalyzer(Version.LUCENE_33);
//索引配置
IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_33, a);
//创建一个写索引,维护索引的IndexWriter对象
IndexWriter writer=new IndexWriter(d, config);
//创建索引文档对象
Document doc1=new Document();
Fieldable f=new Field("content",s1,Store.YES,Index.ANALYZED);
//往文档中添加字段
doc1.add(f);
doc1.add(new Field("title","doc 1",Store.YES,Index.ANALYZED));
//往索引目录中添加要索引的文档
writer.addDocument(doc1);
//重新优化组织索引
writer.optimize();
//关闭,把内存中的内容写到索引目录中
writer.close();
}
2、搜索--查询索引
IndexReader==>读索引
Searcher==>索引查询器
Analyzer==>分词组件
QueryParser ===>查询解析器
Query ==>查询对象
public void searchIndex() throws Exception{
//索引目录
Directory d=new SimpleFSDirectory(new File("f:/test/index"));
//分词器
Analyzer a=new SimpleAnalyzer(Version.LUCENE_33);
//打开索引
IndexReader reader=IndexReader.open(d, true);
//创建索引查询对象
IndexSearcher searcher=new IndexSearcher(reader);
String key="chengdu";
//把输入的关键字变成Query对象,需要用到查询解析器
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
//把查询的内容变成(解析成)Query对象
Query q=parser.parse(key);
//查询前5条数据
TopDocs tds= searcher.search(q, 5);
//获得返回的文档
ScoreDoc[] sds= tds.scoreDocs ;
for(ScoreDoc sd:sds){
//System.out.println("分值:"+sd.score);
int docNum=sd.doc;
//根据文档号取出文档
Document doc= searcher.doc(docNum);
//取出文档中的字段的内容
String title=doc.get("title");
String content=doc.get("content");
System.out.println("title:"+title);
System.out.println("content:"+content);
System.out.println("-------------------------");
}
searcher.close();
reader.close();
}
Luence应用中的核心类:
IndexWriter
IndexSearcher
Query
QueryParser
Analyzer
Directory
三、Luence API详解
1、索引目录Directory==用来存放索引文件内容的目录。
2、分词器Analyzer
A、SimpleAnalyzer==>按空格分词
B、StandardAnalyzer==>对停词进行处理以后的分词器
中文分词
==>单字分词--StandardAnalyzer,一个字就是一词。
==>二分法--CJKAnalyzer
==>词库(字典)分词法===>SmartChineseAnalyzer
分词测试代码
private void analyzer(Analyzer a,String s) throws Exception{
//Analyzer a=new SimpleAnalyzer(Version.LUCENE_33);
//String s="this is a book";
TokenStream ts= a.tokenStream("title", new StringReader(s));
while(ts.incrementToken()){
System.out.println(ts.toString());
}
System.out.println("--------------------");
}
3、Document--索引中一条数据
void add(Fieldable field)
String get(String name)
4、Fieldable--字段(名称,文本值)
new Field("content","广州人",Store.YES,Index.ANALYZED)
Store.YES/Store.NO表示要存储,把整个字段的值原样保存起来。
Index参数
Index.NO-->该字段不会到索引文件中
Index.NOT_ANALYZED-->不用进行分词处理,整个字段的值直接存到索引文件中
Index.ANALYZED-->要对该字段进行分词处理,可以查询。
5、IndexWriter-->索引维护--增量索引及全索引
CUD的方法
添加:
void addDocument(Document doc)
void addDocument(Document doc, Analyzer analyzer)
void addDocuments(Collection<Document> docs)
void addIndexes(Directory... dirs)
void addIndexes(IndexReader... readers)
删除:
void deleteAll()
void deleteDocuments(Query query)
void deleteDocuments(Term term)
void deleteDocuments(Term... terms)
修改(先删除,再添加,并调整位置):
void updateDocument(Term term, Document doc)
void updateDocuments(Term delTerm, Collection<Document> docs)
其它:
void optimize()
void commit()
void close()
6、IndexReader-->读索引
void deleteDocument(int docNum)
int deleteDocuments(Term term)
Document document(int n)
int maxDoc()
static IndexReader open(Directory directory)
TermEnum terms()
7、IndexSearcher--查询索引
Document doc(int docID)
int maxDoc()
TopDocs search(Query query, int n)
...
TopDocs search(Weight weight, Filter filter, int nDocs)
to be or not to be.
四、Luence中的查询
1、两种构建查询对象(Query)的方式
A、QueryParser来解析
public void search1() throws Exception{
String key="广州";
//通过QueryParser来解析查询对象
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
//把查询的内容变成(解析成)Query对象
Query query=parser.parse(key);
System.out.println(query.getClass());
search(query,key);
}
B、使用具体的Query类来创建查询对象
public void search2() throws Exception{
String key="广州";
//直接使用具体的Query类来构建查询
Query query=new TermQuery(new Term("content",key));
search(query,key);
}
2、查询段落
用双引号或者phraseQuery
public void phraseQuery() throws Exception{
String key="\"中华大地\"";
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
Query query=parser.parse(key);
search(query);
PhraseQuery q=new PhraseQuery();
q.add(new Term("content","中华"));
q.add(new Term("content","大地"));
search(q);
}
3、通配符查询,使用?或者*
public void wildcardQuery() throws Exception{
String key="中?";
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
Query query=parser.parse(key);
search(query);
WildcardQuery q=new WildcardQuery(new Term("content","中?"));
search(q);
}
4、相似查询,使用~0.5
public void fuzzyQuery() throws Exception{
String key="中华~0.4";
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
Query query=parser.parse(key);
search(query);
FuzzyQuery q=new FuzzyQuery(new Term("content","中华"),0.5f);
search(q);
}
5、领近查询,
6、范围查询
public void rangeQuery() throws Exception{
//区间值在结果中
String key="[20020101 TO 20020102]";
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
Query query=parser.parse(key);
search(query);
System.out.println("------------");
//大括号则不把区间值包含在结果中
key="{20020101 TO 20020105}";
parser=new QueryParser(Version.LUCENE_33, "content", a);
query=parser.parse(key);
search(query);
System.out.println("-----------");
//使用代码实现半开半闭区间查询
TermRangeQuery trq=new TermRangeQuery("content","20020101","20020105",false,true);
search(trq);
}
7、逻辑或查询OR
OR 空格 ||
public void booleanOrQuery() throws Exception{
String key="万岁 title:智";
QueryParser parser=new QueryParser(Version.LUCENE_33, "content", a);
Query query=parser.parse(key);
search(query);
key="万岁 OR title:智";
key="万岁 || title:智";
parser=new QueryParser(Version.LUCENE_33, "content", a);
query=parser.parse(key);
search(query);
}
8、逻辑与查询AND
AND及&&
9、逻辑非查询NOT
NOT及!
注意NOT不能作为第一个条件。
五、基于Luence的CRUD综合实例--基于传统SSH--新闻发布系统
java site:www.csdn.net
新闻的管理功能。CRUD.
1、域模型
News
标题
内容
发布时间
作者
来源
摘要
录入时间
public class News {
private Long id;
// 标题
private String title;
// 内容
private String content;
// 发布时间
private Date publishTime;
// 作者
private String author;
// 来源
private String source;
// 摘要
private String intro;
// 录入时间
private Date inputTime = new Date();
....
getter及setter
}
2、DAO层的接口及实现
A、接口
public interface INewsDao {
Long save(News o);
void delete(Long id);
void update(Long id, News o);
News get(Long id);
List<News> query(String scope, Object[] params, int begin, int max);
}
B、测试
C、实现
3、Hibernate与Spring的集成
A、导包
B、DAO操作数据库的模板Template,HibernateTemplate
public class NewsDaoImpl extends HibernateDaoSupport implements INewsDao{
@Override
public Long save(News o) {
this.getHibernateTemplate().persist(o);
return o.getId();
}
@Override
public void delete(Long id) {
getHibernateTemplate().delete(get(id));
}
@Override
public void update(Long id, News o) {
o.setId(id);
getHibernateTemplate().merge(o);
}
@Override
public News get(Long id) {
return getHibernateTemplate().get(News.class, id);
}
@SuppressWarnings("unchecked")
@Override
public List<News> query(final String scope, final Object[] params, final int begin, final int max) {
return getHibernateTemplate().executeFind(new HibernateCallback<List<News>>() {
@SuppressWarnings("unchecked")
@Override
public List<News> doInHibernate(Session session)
throws HibernateException, SQLException {
Query query= session.createQuery("from News obj where"+scope);
if(params!=null){
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
}
//处理分页
if(begin>=0&&max>0){
query.setFirstResult(begin);
query.setMaxResults(max);
}
return query.list();
}
});
}
}
C、配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="/hibernate.cfg.xml"></property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="newsDao" class="cn.itcast.gz.dao.impl.NewsDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>