程序员人生 网站导航

Lucene之完整搜索实例

栏目:互联网时间:2015-03-10 08:30:05

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); */ } } } }

效果图:

索引器:



搜索器:


------分隔线----------------------------
------分隔线----------------------------

最新技术推荐