Lucene之完整搜索实例
来源:程序员人生 发布时间:2015-03-10 08:30:05 阅读次数:2443次
1、创建索引器:
package yushibujue;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;
import tool.FileList;
import tool.FileText;
public class LuceneIndexer {
private JTextField jtfa;
private JButton jba;
private JTextField jtfb;
private JButton jbb;
private JButton jbc;
private static JTextArea jta;
//索引器外观类
private void createAndShowGUI(){
//设置跨平台外观感觉
String lf=UIManager.getCrossPlatformLookAndFeelClassName();
//GTK外观感觉
//String lf="com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
//Sysetm外观感觉
// String lf=UIManager.getSystemLookAndFeelClassName();
//windows外观感觉
// String lf="com.sun.java.swing.plaf.WindowsLookAndFeel";
//Metal外观感觉
//String lf="javax.swing.plaf.metal.MetalLookAndFeel";
//common use
try{
UIManager.setLookAndFeel(lf);
}catch(Exception e){
JOptionPane.showMessageDialog(null,"没法设定外观感觉!");
}
//java 感觉
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame=new JFrame("YUSHIBUJUE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JFileChooser fc=new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
Container con=frame.getContentPane();
con.setLayout(new BorderLayout());
JPanel jpup=new JPanel();
jpup.setLayout(new GridLayout(3,2));
jtfa=new JTextField(30);
jba=new JButton("选择被索引的文件寄存路径");
jba.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
int r=fc.showOpenDialog(null);
if(r==JFileChooser.APPROVE_OPTION){
jtfa.setText(fc.getSelectedFile().getPath());
jbc.setEnabled(true);
}
}
}
);
jtfb=new JTextField(30);
JButton jbb=new JButton("选择索引的寄存路径");
jbb.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
int r= fc.showOpenDialog(null);
if(r==JFileChooser.APPROVE_OPTION){
jtfb.setText(fc.getSelectedFile().getPath());
jbc.setEnabled(true);
}
}
}
);
JLabel jl=new JLabel("");
jbc=new JButton("建立索引");
jbc.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
LuceneIndeerTool.index(jtfa.getText(),jtfb.getText());
//jbc.setEnabled(false);
}catch(Exception ee){
ee.printStackTrace();
jbc.setEnabled(true);
JOptionPane.showMessageDialog(null, "索引创建失败!");
System.out.println(ee.getMessage());
}
}
}
);
jpup.add(jtfa);
jpup.add(jba);
jpup.add(jtfb);
jpup.add(jbb);
jpup.add(jl);
jpup.add(jbc);
jta=new JTextArea(10,60);
JScrollPane jsp=new JScrollPane(jta);
con.add(jpup,BorderLayout.NORTH);
con.add(jsp,BorderLayout.CENTER);
frame.setSize(200,100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
try{
new LuceneIndexer().createAndShowGUI();
}catch(Exception e){
JOptionPane.showMessageDialog(null, "程序加载失败!");
}
}
}
);
}
//使用内部类LuceneIndexerTool来实现索引工作,这样就能够把索引建立的情况反应在文本框里面了
static class LuceneIndeerTool{
//创建索引,被索引的文件的路径,索引的路径
public static void index(String filesPath,String indexPath)throws IOException{
//建立索引器,我采取lucene4.7写法
File path=new File(indexPath);
SimpleFSDirectory indexDir=new SimpleFSDirectory(path);//读取被索引的文件目录
CJKAnalyzer analyzer=new CJKAnalyzer(Version.LUCENE_47);//创建1个2分法分析器
IndexWriterConfig conf=new IndexWriterConfig(Version.LUCENE_47, analyzer);
IndexWriter writer=new IndexWriter(indexDir,conf);
/* Directory dir=FSDirectory.open(new File(indexPath));
Analyzer analyzer=new StandardAnalyzer();
IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_4_10_2,analyzer);
IndexWriter writer=new IndexWriter(dir,config);*/
//递归遍历文件目录来建立索引
String s[]=FileList.getFiles(filesPath);
int len=s.length;
for(int i=0;i<len;i++){
File f=new File(s[i]);
String ext=getExt(f);//获得扩大名
if(ext.equalsIgnoreCase("htm")||ext.equalsIgnoreCase("html")){
Document doc=new Document();
//filename field
String filename=f.getName();
Field field=new Field("filename",filename,Field.Store.YES,Field.Index.ANALYZED);
doc.add(field);
//uri field
String uri=f.getPath();
field=new Field("uri",uri,Field.Store.YES,Field.Index.NO);
doc.add(field);
//cdate field
Date dt=new Date(f.lastModified());
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd E");
String cdate=sdf.format(dt);
field=new Field("cdate",cdate,Field.Store.YES,Field.Index.NO);
doc.add(field);
//size field
double si=f.length();
String size="";
if(si>1024){
size=String.valueOf(Math.floor(si/1024)+"K");
}else{
size=String.valueOf(si)+"Bytes";
}
field=new Field("size",size,Field.Store.YES,Field.Index.NO);
doc.add(field);
//text field
String text=FileText.getText(f);
field=new Field("text",text,Field.Store.YES,Field.Index.ANALYZED);
doc.add(field);
//digest field
String digest="";
if(text.length()>200){
digest=text.substring(0, 200);
}else{
digest=text;
}
field=new Field("digest",digest,Field.Store.YES,Field.Index.ANALYZED);
doc.add(field);
//归入索引
writer.addDocument(doc);
jta.setText(jta.getText()+"已归入索引: " +f+"
");
}
}
//关闭索引器
writer.close();
JOptionPane.showMessageDialog(null, "索引建立终了!","提示", JOptionPane.INFORMATION_MESSAGE);
}
public static String getExt(File f){
String s=f.getName();
try{
s=s.substring(s.lastIndexOf(".")+1);
}catch(Exception e){
s="";
}
return s;
}
}
}
2、创建搜索器:
package yushibujue;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
public class LuceneSearcher {
private JTextField jtfa;
private JButton jba;
private JTextField jtfb;
private JButton jbb;
private JButton jbc;
private static JTextArea jta;
private JTextField jtfc;
private JButton jbd;
private JButton jbe;
private void createAndShowGUI(){
//设置跨平台外观感觉
String lf=UIManager.getCrossPlatformLookAndFeelClassName();
//GTK外观感觉
//String lf="com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
//Sysetm外观感觉
// String lf=UIManager.getSystemLookAndFeelClassName();
//windows外观感觉
// String lf="com.sun.java.swing.plaf.WindowsLookAndFeel";
//Metal外观感觉
//String lf="javax.swing.plaf.metal.MetalLookAndFeel";
//common use
try{
UIManager.setLookAndFeel(lf);
}catch(Exception ce){
JOptionPane.showMessageDialog(null, "没法设定外观感觉!");
}
//java feel
//java 感觉
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame=new JFrame("YUSHIBUJUE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JFileChooser fc=new JFileChooser();
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
Container con=frame.getContentPane();
con.setLayout(new BorderLayout());
JPanel jpup=new JPanel();
jpup.setLayout(new GridLayout(2,2));
jtfa=new JTextField(30);
jba=new JButton("选择索引的寄存路径");
jba.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
int r=fc.showOpenDialog(null);
if(r==JFileChooser.APPROVE_OPTION){
jtfa.setText(fc.getSelectedFile().getPath());
}
}
}
);
jtfb=new JTextField(30);
JButton jbb=new JButton("搜索");
jbb.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
String indexPath=jtfa.getText();
String phrase=jtfb.getText();
new LuceneSearcherTool().search(phrase,indexPath);
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "搜索失败","提示",JOptionPane.ERROR_MESSAGE);
}
}
}
);
jpup.add(jtfa);
jpup.add(jba);
jpup.add(jtfb);
jpup.add(jbb);
jta=new JTextArea(10,30);
JScrollPane jsp=new JScrollPane(jta);
JPanel jpdown=new JPanel();
jpdown.setLayout(new FlowLayout());
jtfc=new JTextField(35);
jbd=new JButton("设定导前途径");
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
jbd.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
int r=fc.showOpenDialog(null);
if(r==JFileChooser.APPROVE_OPTION){
jtfc.setText(fc.getSelectedFile().getPath());
}
}
});
jbe=new JButton("导出搜索结果");
jbe.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
File f=new File(jtfc.getText());
FileWriter fw=new FileWriter(f);
PrintWriter pw=new PrintWriter(fw);
pw.write(jta.getText());
pw.flush();
pw.close();
JOptionPane.showMessageDialog(null, "写入文件成功!","提示",JOptionPane.INFORMATION_MESSAGE);
}catch(IOException ioe){
JOptionPane.showMessageDialog(null, "写入文件失败!","提示",JOptionPane.ERROR_MESSAGE);
}
}
}
);
jpdown.add(jtfc);
jpdown.add(jbd);
jpdown.add(jbe);
con.add(jpup,BorderLayout.NORTH);
con.add(jsp,BorderLayout.CENTER);
con.add(jpdown,BorderLayout.SOUTH);
frame.setSize(200,100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new LuceneSearcher().createAndShowGUI();
}
});
}
static class LuceneSearcherTool{
//履行搜索--搜索关键词、索引的路径
public static void search(String phrase,String indexPath)throws IOException{
//建立索引器
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(indexPath))));
//搜索text字段
Term t=new Term("text",phrase);
//生成Query对象
TermQuery query=new TermQuery(t);
TopDocs topDocs=searcher.search(query,20);
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
jta.setText("检索到的记录数量:"+topDocs.totalHits+"
");
jta.setText(jta.getText()+"*******************"+"
");
System.out.println("查询结果总数:"+topDocs.totalHits+"最大的评分:"+topDocs.getMaxScore());
for(int i=0;i<scoreDocs.length;i++){
int doc=scoreDocs[i].doc;
Document document = searcher.doc(doc);
if(document==null){
continue;
}
//取得filename字段,此处采取了强迫转换(try)
Field field=(Field) document.getField("filename");
String filename=field.stringValue();
//uri字段
field=(Field) document.getField("uri");
String uri=field.stringValue();
//cdate字段
field=(Field) document.getField("cdate");
String cdate =field.stringValue();
//digest 字段
field=(Field) document.getField("digest");
String digest=field.stringValue();
StringBuffer sb=new StringBuffer();
sb.append("URI:"+uri+"
");
sb.append("filename:"+filename+"
");
sb.append("cdate:"+cdate+"
");
sb.append("digest:"+digest+"
");
sb.append("-------------------"+"
");
jta.setText(jta.getText()+sb.toString());
/* System.out.println("content:"+document.get("content"));
System.out.println("id:" + scoreDocs[i].doc + " scors:" + scoreDocs[i].score+"---index--"+scoreDocs[i].shardIndex);
*/
}
}
}
}
效果图:
索引器:
搜索器:
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠