Lucene之完整搜索實例
來源:程序員人生 發布時間:2015-03-10 08:30:05 閱讀次數:2600次
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);
*/
}
}
}
}
效果圖:
索引器:

搜索器:

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈