精华内容
下载资源
问答
  • Oracl对本地文件全文检索

    千次阅读 2013-07-03 11:12:09
    Oracle Text支持对本地文件的检索 它的实现是依靠参数datastore和filter的组合。在数据库的文本列中只保存指向硬盘文件的指针。建立索引的时候,oracle读取硬盘上的文件并且将索引存储在oracle数据库中。 Oracle...


     

     

    Oracle Text支持对本地文件的检索

    它的实现是依靠参数datastore和filter的组合。在数据库的文本列中只保存指向硬盘文件的指针。建立索引的时候,oracle读取硬盘上的文件并且将索引存储在oracle数据库中。

    Oracle支持对很多格式的文件的文本检索,包括文本文件Txt,  Html文件, Word文档,  Excel表格,  PowerPoint 的文本检索,也支持PDF(pdf版本1.4目前还不支持)。

          而且配合Lexer参数很好的支持了中文字符集的检索。

       

    具体实现方法:

            首先,建立存储选项参数。制定DATASTORE参数为FILE_DATASTROE,提示Oracle从文件路径中索引文本。

                 然后制定path参数,你可以指定多个文件存储的文件路径 ,windows环境用”;”号间隔(Path1;Path2;Path3;;),Unix环境用:号间隔(Path1:Path2:Path3::)

    BEGIN
    CTX_DDL.CREATE_PREFERENCE( 'my_datastore_prefs', 'FILE_DATASTORE' );
    CTX_DDL.SET_ATTRIBUTE( 'my_datastore_prefs', 'path', 'C:\TEMP' );
    END;
    /

     

            下一步,建立保存这些文件名称的表。Id列是主键,title列是对文本的简单说明,thefile列保存着磁盘中Path目录下文件的名称。文件必须能够在Path路径下找到,否则Oracle会报文件无法访问的错误信息。
            然后向表中插入数据,注意:thefile列保存的必须是服务器上的指定的Path路径下面的文件。

     

     
    CREATE TABLE mydocs( id NUMBER PRIMARY KEY, title VARCHAR2(255), thefile 
    VARCHAR2(255) );
     
    INSERT INTO mydocs( id, title, thefile ) VALUES( 1, 'Document1', 'WordDoc1.doc' 
    );
    INSERT INTO mydocs( id, title, thefile ) VALUES( 2, 'Document2', 'WordDoc2.doc' 
    );
    INSERT INTO mydocs( id, title, thefile ) VALUES( 3, 'Document3', 'WordDoc3.doc' 
    );
    COMMIT;
     

     

    建立全文索引,使用参数Datastore和Filter,Lexer 。 Filter可以帮助Oracle识别不同格式文件,可以是文本文件,Word文档,Pdf文档等。Lexer用来保证可以很好的从文件中索引中文信息。

     

     
    CREATE INDEX mydocs_text_index ON mydocs(thefile) INDEXTYPE IS ctxsys.context
        PARAMETERS('datastore my_datastore_prefs Filter ctxsys.inso_filter Lexer my_lexer');
     
    --
    -- 测试是否索引文件成功
    -- 
    SELECT id,title
      FROM mydocs
     WHERE contains( thefile, '你好' ) > 0;

     

     

     

    指定路径带来的相关问题:

    如CTX_DDL.SET_ATTRIBUTE( 'my_datastore_prefs', 'path', 'c:\TEMP;c:\docs' );
    如果在2个目录中均有同名的文件1.doc,如果在thefile列中保存的仅仅是文件名称 1.doc,则Oracle顺序查找路径下的文件,这样就会索引2次在C:\TEMP下的文件1.doc. 我们可以通过加上文件的路径信息。
     
    在维护文档修改的时候同步索引的问题:
    如果你修改了路径下面的某个文件的内容,加入了文本或者删除了文本,Oracle在同步的时候不会察觉到文档的内容的修改。有一个方法可以保证同步:
      修改了内容之后,更新一下表thefile的信息,但仍保证文本路径不变。
      update mydocs set thefile=’c:\source.doc’ where thefile=’c:\source.dco’
     再次执行同步索引的时候,Oracle才会保持文档内容同步。
     
    关于建立以及同步索引的时候发生的错误信息可以从ctx_user_index_errors用户视图中查看。

     

     

     

    Oracle Text 支持检索对网页的文本检索

    通过在表里面存储网络上各种格式的文本文件,HTML文件的路径Url。Oracle在建立索引的时候,可以顺着Url读取文件的流信息,并且将索引存储在磁盘上。这样通过本地查找索引可以获得有用的网页的Url。

    通过自定义Datastore选项,指定URL_DATASTORE 类型。它支持Http访问,和Ftp访问,本地文件系统的访问

        存储在文本列中的Url格式如下:
     [URL:]<access_scheme>://<host_name>[:<port_number>]/[<url_path>]
     

    access_scheme 字符串可以是ftp, http, 或者 file. 例如:

    http://mymachine.us.oracle.com/home.html

    Note:

    login:password@ 格式的语法只有在Ftp访问形式下才有效


    URL_DATASTORE 参数

    URL_DATASTORE的一些参数,其中timeout,proxy是经常用到的:

    Attribute

    Attribute Values

    timeout

    Specify the timeout in seconds. The valid range is 15 to 3600 seconds. The default is 30.这个参数根据网络性能调整。

    maxthreads

    Specify the maximum number of threads that can be running simultaneously. Use a number between 1and 1024. The default is 8.

    urlsize

    Specify the maximum length of URL string in bytes. Use a number between 32 and 65535. The default is 256.

    maxurls

    Specify maximum size of URL buffer. Use a number between 32 and 65535. The defaults is 256.

    maxdocsize

    Specify the maximum document size. Use a number between 256 and 2,147,483,647 bytes (2 gigabytes). The defaults is 2,000,000.

    http_proxy

    Specify the host name of http proxy server. Optionally specify port number with a colon in the form hostname:port

    ftp_proxy

    Specify the host name of ftp proxy server. Optionally specify port number with a colon in the form hostname:port.

    no_proxy

    Specify the domain for no proxy server. Use a comma separated string of up to 16 domain names.

     
     
    索引建立过程:
    首先建立自己的URL_DATASTORE选项。如下指定了代理,Timeout时间。
    begin
     ctx_ddl.create_preference('URL_PREF','URL_DATASTORE');
    ctx_ddl.set_attribute('URL_PREF','Timeout','300');
    end;
     
    建立存储Url路径的表
     
    create table urls(id number primary key, url varchar2(2000));
    insert into urls values(1,'http:// http://intranet-center/');
    insert into urlsvalues(2,'http://founderweb:9080/default.jsp');
    commit;
     
    建立索引,索引Html文件可以使用HTML_SECTION_GROUP
    create index datastores_text on urls ( url ) 
      indextype is ctxsys.context 
      parameters ( 'Datastore URL_PREF Lexer my_lexer Section group ctxsys.HTML_SECTION_GROUP' ); 

     

    select token_text from dr$datastore_text$i;
     
    关于建立以及同步索引的时候发生的错误信息可以从ctx_user_index_errors用户视图中查看。
     
     
     
     
     
     
     
     

    解锁ctxsys用户,在system用户下操作  

    alter user ctxsys account unlock;  

    将ctx_ddl包的操作权限赋给用户  

    grant execute on ctx_ddl to 用户;  

    GRANT   ctxapp TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_cls TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_ddl TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_doc TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_output TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_query TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_report TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_thes TO 用户;

    GRANT EXECUTE ON ctxsys.ctx_ulexer TO 用户;

     

    创建词法分析器
     ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer');
     
    建立存储选项参数:
    exec CTX_DDL.CREATE_PREFERENCE('my_datastore_prefs', 'FILE_DATASTORE' );
    FILE_DATASTORE:检索本地文档
    <删除:ctx_ddl.drop_preference(‘my_datastore_prefs’);>
    Exec CTX_DDL.SET_ATTRIBUTE('my_datastore_prefs', 'path', 'D:\sss' );
    D:\sss:检索全路径
     
     
    建表和插入数据:
    CREATE TABLE mydocs( id NUMBER PRIMARY KEY, title VARCHAR2(255), thefile 
    VARCHAR2(255) );
    INSERT INTO mydocs( id, title, thefile ) VALUES( 1, 'Document1', 'D:\sss\WordDoc1.doc');
    INSERT INTO mydocs( id, title, thefile ) VALUES( 2, 'Document2', ' D:\sss\WordDoc2.doc' );
    INSERT INTO mydocs( id, title, thefile ) VALUES( 3, 'Document3', ' D:\sss\WordDoc3.doc' );
    COMMIT;
     
     
    建立索引:
    CREATE INDEX mydocs_index ON mydocs(thefile) INDEXTYPE IS ctxsys.context   PARAMETERS('datastore my_datastore_prefs Filter ctxsys.inso_filter Lexer my_lexer');
     
     
     
     
    索引同步:
    ctx_ddl.sync_index(myindex);
     
     
    删除过期索引:
    ctx_ddl.optimize_index(myidx, 'FULL');
    
    
    
    
    oracle 发现全文检索不支持文件名为汉字的文件,以及office 07以上的版本    有什么解决的好方案请大家分享下

    展开全文
  • 借助第三方工具对本地的文档(包含但不局限于txt、PDF、word、excel、PowerPoint)中的文本内容进行全文检索 支持用户输入文本进行查询,查询出来的文本,应该在界面中给予高亮 有图形化的界面,支持在整个程序中直接...

    需求

    1. 借助第三方工具对本地的文档(包含但不局限于txt、PDF、word、excel、PowerPoint)中的文本内容进行全文检索
    2. 支持用户输入文本进行查询,查询出来的文本,应该在界面中给予高亮
    3. 有图形化的界面,支持在整个程序中直接打开相应的文档或者文件

    提示

    类似的工具诸如DocFetcher,Mendeley里面全文检索功能等。可以试下用DocFetcher来了解相关的功能。

    可以基于Lucene这个文本索引的库来做;可以通过一个叫做lukeall软件来查看lucene索引中的文档内容。

    实现

    1、解析不同文件类型的工具类

    import java.io.File;
    import java.io.FileInputStream;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    /**  
    *excel文件解析工具类
    */
    public class ExcelParse {
    	public static String parseFile(String filePath){
    		StringBuffer sb=new StringBuffer();
    		try {
                File excel = new File(filePath);
                if (excel.isFile() && excel.exists()) {   //判断文件是否存在
                    String[] split = excel.getName().split("\\.");  //.是特殊字符,需要转义!!!!!
                    Workbook wb;
                    //根据文件后缀(xls/xlsx)进行判断
                    if ( "xls".equals(split[1])){
                        FileInputStream fis = new FileInputStream(excel);   //文件流对象
                        wb = new HSSFWorkbook(fis);
                    }else if ("xlsx".equals(split[1])){
                        wb = new XSSFWorkbook(excel);
                    }else {
                        System.out.println("文件类型错误!");
                        return null;
                    }
                    //开始解析
                    Sheet sheet = wb.getSheetAt(0);     //读取sheet 0
                    int firstRowIndex = sheet.getFirstRowNum();   //第一行是列名
                    int lastRowIndex = sheet.getLastRowNum();
                    //System.out.println("firstRowIndex: "+firstRowIndex);
                    //System.out.println("lastRowIndex: "+lastRowIndex);
                    for(int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) {   //遍历行 按行输出
                        //System.out.println("rIndex: " + rIndex);
                        Row row = sheet.getRow(rIndex);
                        if (row != null) {
                            int firstCellIndex = row.getFirstCellNum();
                            int lastCellIndex = row.getLastCellNum();
                            for (int cIndex = firstCellIndex; cIndex < lastCellIndex; cIndex++) {   //遍历列
                                Cell cell = row.getCell(cIndex);
                                if (cell != null) {
                                    sb.append(cell.toString()+"\n");
                                }
                            }
                        }
                    }
                } else {
                    System.out.println("找不到指定的文件");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    		return sb.toString();
    	}
    }
    
    import java.io.File;
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.text.PDFTextStripper;
    /**  
    * pdf文件解析工具类
    */
    public class PDFParse {
    	 public static  String parsePDF(String path){
        	String result = "";
        	try{
            	PDDocument document = PDDocument.load(new File(path));
                PDFTextStripper stripper = new PDFTextStripper();
                stripper.setSortByPosition(true);
                for (int p = 1; p <= document.getNumberOfPages(); ++p)
                {
                    stripper.setStartPage(p);
                    stripper.setEndPage(p);
                    String text = stripper.getText(document);
                    result += text;
                }   		
        	}catch(Exception e){
        		e.printStackTrace();
        	}
        	return result;    	
        }
    	 
    	 public static void main(String[] args) {
    		String s =parsePDF("E:\\ftp上传\\ftpTest\\数据库基础知识.pdf");
    		System.out.println(s);
    	 }
    }
    
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.hslf.extractor.PowerPointExtractor;
    import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
    import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
    import org.apache.xmlbeans.XmlException;
    /**  
    * ppt文件解析工具类
    */
    public class PPTParse {
    
    	//直接抽取幻灯片的全部内容
        public static String pptParse(String filePath) throws IOException, XmlException, OpenXML4JException{
        	String content="";
        	if(filePath.toLowerCase().endsWith("ppt")){
        		File file = new File(filePath);
            	FileInputStream fin=new FileInputStream(file);
                PowerPointExtractor extractor=new PowerPointExtractor(fin);
                content=extractor.getText();
        	}else if (filePath.toLowerCase().endsWith("pptx")) {
    			content=new XSLFPowerPointExtractor(POIXMLDocument.openPackage(filePath)).getText();
    		}
            return content;
        }
    }
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.apache.poi.POIXMLDocument;
    import org.apache.poi.POIXMLTextExtractor;
    import org.apache.poi.hwpf.HWPFDocument;
    import org.apache.poi.hwpf.extractor.WordExtractor;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    /**  
    *word文件解析工具类
    */
    public class WordParse {
    	//方式一:返回字符串集合
    	public static List<String> readWord(String filePath) throws Exception{
    		List<String> linList = new ArrayList<String>();
    		String buffer = "";
    		try {
    			if (filePath.endsWith(".doc")) {
    				InputStream is = new FileInputStream(new File(filePath));
    				WordExtractor ex = new WordExtractor(is);
    				buffer = ex.getText();
    				ex.close();
    				if(buffer.length() > 0){
    					//使用回车换行符分割字符串
    					String [] arry = buffer.split("\\r\\n");
    					for (String string : arry) {
    						linList.add(string.trim());
    					}
    				}
    			} else if (filePath.endsWith(".docx")) {
    				OPCPackage opcPackage = POIXMLDocument.openPackage(filePath);
    				POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);
    				buffer = extractor.getText();
    				extractor.close();
    				if(buffer.length() > 0){
    					//使用换行符分割字符串
    					String [] arry = buffer.split("\\n");
    					for (String string : arry) {
    						linList.add(string.trim());
    					}
    				}
    			} else {
    				return null;
    			}
    			
    			return linList;
    		} catch (Exception e) {
    			System.out.print("error---->"+filePath);
    			e.printStackTrace();
    			return null;
    		}
    	}
    	//方式二:返回字符串
    	public static String parseFile(String filePath) {
    		File docFile= new File(filePath);
            String fileName = docFile.getName();
            String docContent = null;
            FileInputStream fis = null;
            try {
                 fis = new FileInputStream(docFile);
                if (fileName.toLowerCase().endsWith("doc")) {
                    HWPFDocument doc = new HWPFDocument(fis);
                    docContent = doc.getDocumentText();
                } else if (fileName.toLowerCase().endsWith("docx")) {
                    XWPFDocument xdoc = new XWPFDocument(fis);
                    XWPFWordExtractor extractor = new XWPFWordExtractor(xdoc);
                    docContent = extractor.getText();
                } else {
                }
            } catch (Exception e) {
            	e.printStackTrace();
            }
            return docContent;     //返回文本内容
        }
    }
    

    注意:解析word时,如果是直接导入jar包的方式,可能会出现XWPFWordExtractor报错信息。需要另外用到依赖包xmlbeans-2.6.0.jar。maven配置方式会直接关联。

    2、创建、查询lucene索引

    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import org.apache.commons.io.FileUtils;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.document.LongPoint;
    import org.apache.lucene.document.StoredField;
    import org.apache.lucene.document.TextField;
    import org.apache.lucene.index.DirectoryReader;
    import org.apache.lucene.index.IndexReader;
    import org.apache.lucene.index.IndexWriter;
    import org.apache.lucene.index.IndexWriterConfig;
    import org.apache.lucene.index.Term;
    import org.apache.lucene.search.IndexSearcher;
    import org.apache.lucene.search.Query;
    import org.apache.lucene.search.ScoreDoc;
    import org.apache.lucene.search.TermQuery;
    import org.apache.lucene.search.TopDocs;
    import org.apache.lucene.store.Directory;
    import org.apache.lucene.store.FSDirectory;
    import org.wltea.analyzer.lucene.IKAnalyzer;
    import com.example.tool.ExcelParse;
    import com.example.tool.PDFParse;
    import com.example.tool.PPTParse;
    import com.example.tool.WordParse;
    public class LuceneIndex {
    	static IndexWriterConfig config =null;
    	static IndexWriter indexWriter =null;
    	 private static boolean deleteDir(File dir) {
    	        if (dir.isDirectory()) {
    	            String[] children = dir.list();
    	            //递归删除目录中的子目录下
    	            for (int i=0; i<children.length; i++) {
    	                boolean success = deleteDir(new File(dir, children[i]));
    	                if (!success) {
    	                    return false;
    	                }
    	            }
    	        }
    	        // 目录此时为空,可以删除
    	        return dir.delete();
    	    }
    	 
    	 /**
    	 * 查询字符编码
    	 */
    	public static String codeStringPlus(String fileName) throws Exception {
    		BufferedInputStream bin = null;
    		String code = null;
    		try {
    			bin = new BufferedInputStream(new FileInputStream(fileName));
    			int p = (bin.read() << 8) + bin.read();
    			switch (p) {
    			case 0xefbb:
    				code = "UTF-8";
    				break;
    			case 0xd0cf:
    				code="gb2312";
    				break;
    			case 0xfffe:
    				code = "Unicode";
    				break;
    			case 0xfeff:
    				code = "UTF-16BE";
    				break;
    			default:
    				code = "GBK";
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			bin.close();
    		}
    		return code;
    	}
    	
    	//递归处理目录
    	public static void traverseFolder(File file) throws Exception{
    		File[] files = file.listFiles();
            for (File file1:files){
                //判断当前文件是否为文件夹
                if (file1.isDirectory()){
                    traverseFolder(file1);
                }else{
                	inputStored(indexWriter, file1);
                }
            }
    	}
    	//创建索引
    	public static void createIndex(String dirPath) throws Exception {
          //1、创建一个Directory对象,指定索引库保存的位置。
          //把索引库保存在内存中(保存在内存中,程序关闭就丢失了)
          //Directory directory = new RAMDirectory();
    		String path="E:\\logs\\index";
    		File file = new File(path);
    		if (file.exists()) {
    			deleteDir(file);//每次创建索引库前,先删除之前创建的索引库中的内容
    		}
          //把索引库保存在磁盘
          Directory directory = FSDirectory.open(file.toPath());
          // 2、基于Directory对象创建一个IndexWeiter对象
          //标准分析器
          //IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
          config = new IndexWriterConfig(new IKAnalyzer());
          indexWriter = new IndexWriter(directory, config);
          //  3、读取磁盘上的文件,对应每个文件创建一个文档对象。
          File dir = new File(dirPath);
          if (dir.isDirectory()) {
        	  traverseFolder(dir);
          }else{
        	  inputStored(indexWriter, dir);
          }
          //6、关闭indexWriter对象
          indexWriter.close();
       }
    
    	private static void inputStored(IndexWriter indexWriter, File f) throws IOException, Exception {
    		//先取文件名
    		  String fileName = f.getName();
    		  //文件路径
    		  String filePath = f.getPath();
    		  //文件内容
    		  String fileContent="";
    		  if (filePath.toLowerCase().endsWith("ppt") || filePath.toLowerCase().endsWith("pptx")) {
    			  fileContent=PPTParse.pptParse(filePath);
    		  }else if (filePath.toLowerCase().endsWith("xls") || filePath.toLowerCase().endsWith("xlsx")) {
    			fileContent=ExcelParse.parseFile(filePath);
    		 }else if (filePath.toLowerCase().endsWith("pdf")) {
    			fileContent=PDFParse.parsePDF(filePath);
    		 }else if (filePath.toLowerCase().endsWith("doc") || filePath.toLowerCase().endsWith("docx")) {
    			fileContent=WordParse.parseFile(filePath);
    		 }else{
    			 fileContent = FileUtils.readFileToString(f,codeStringPlus(filePath));
    		 }
    		  //文件大小
    		  long fileSize = f.length();
    		  //创建Field域
    		  //参数1:域的名称,参数2:域的内容,参数3:是否存储
    		  Field fieldName = new TextField("name", fileName, Field.Store.YES);
    		  Field fieldPath = new StoredField("path",filePath);
    		  Field fieldContent = new TextField("content", fileContent, Field.Store.YES);
    		  Field fieldSizeValue = new LongPoint("size", fileSize);
    		  Field fieldSizeStore = new StoredField("size", fileSize);
    		  //创建文档对象
    		  Document document = new Document();
    		  //4、向文档对象中添加域
    		  document.add(fieldName);
    		  document.add(fieldPath);
    		  document.add(fieldContent);
    		  //document.add(fieldSize);
    		  document.add(fieldSizeValue);
    		  document.add(fieldSizeStore);
    		  //5、把文档对象写入索引库
    		  indexWriter.addDocument(document);
    	}
    	
    
    	/**
         * 查询索引
         * @throws Exception
         */
        public static Map<String,String> searchIndex(String content) throws Exception {
            //1、创建一个Director对象,指定索引库的位置
            Directory directory = FSDirectory.open(new File("E:\\logs\\index").toPath());
            //2、创建一个IndexReader对象
            IndexReader indexReader = DirectoryReader.open(directory);
            //3、创建一个IndexSearcher对象,构造方法中的参数indexReader对象
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            //4、创建一个Query对象,TermQuery  //Term(关键词)包含两部分  关键词所包含的域和关键词本身
            Query query = new TermQuery(new Term("content",content));  //查询content域的包含spring关键词的
            //5、执行查询,得到一个TopDocs对象
            //参数1:查询对象  参数2:查询结果返回的最大记录数
            TopDocs topDocs = indexSearcher.search(query, 10);
            //6、取查询结果的总记录数
            System.out.println("查询总记录数:" + topDocs.totalHits);
            //7、取文档列表
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            Map<String,String> map=new HashMap<String,String>();
            //8、打印文档中的内容
            for (ScoreDoc doc:scoreDocs) {
                //取文档id
                int docId = doc.doc;
                //根据id取文档对象
                Document document = indexSearcher.doc(docId);
                //System.out.println(document.get("name"));
                //System.out.println(document.get("path"));
                //System.out.println(document.get("content"));
                //将文件名作为key,文件内容作为value
                map.put(document.get("name"),document.get("content"));
            }
            //9、关闭IndexReader对象
            indexReader.close();
            return map;
        }
    }
    

    3、窗体类

    public class LuceneJFrame extends JFrame implements ActionListener{
    	JPanel topPane;
    	JScrollPane jp;
    	JLabel lab1;
    	JLabel lab2;
    	JTextField field1;
    	JTextField field2;
    	JButton jButton1;
    	JButton jButton2;
    	static JTextArea tArea;
    	JFileChooser jfc;// 文件选择器 
    	JMenuBar mb;
    	static FgMenu mFile=new FgMenu("文件(F)",KeyEvent.VK_F);//"文件"菜单
    	static JMenuItem miNew=new JMenuItem("新建(N)",KeyEvent.VK_N),
    	miOpen=new JMenuItem("打开(O)...",KeyEvent.VK_O),
    	miSave=new JMenuItem("保存(S)",KeyEvent.VK_S),
    	miFont=new JMenuItem("字体与颜色(F)...",KeyEvent.VK_F),
    	miQuit=new JMenuItem("退出(X)",KeyEvent.VK_X);
    	public LuceneJFrame(String title){
    		super(title);
    		setSize(800, 600);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setLocationRelativeTo(null);//传入参数null 即可让JFrame 位于屏幕中央, 这个函数若传入一个Component ,则JFrame位于该组件的中央
    		topPane = new JPanel();//上面板
    		topPane.setBounds(0,0,800,120);
    		tArea=new JTextArea();//文本域
    		jp=new JScrollPane(tArea);
    		jp.setBounds(0,120,800,440);
    		Font font=new Font("宋体",Font.BOLD,16);
    		tArea.setFont(font);
    		topPane.setLayout(null);//取消JPanel的布局(避免JPanel的setLayout布局与setBounds方法相冲突)
    		this.add(topPane);
    		this.add(jp);
    		this.setLayout(null);
    		luceneIn();
    		dealEvent();
    		addMenus();
    		this.setVisible(true);
    	}
    	
    	public void addMenus(){
    		mb=new JMenuBar();//菜单栏
    		setJMenuBar(mb);
    		mFile.add(miNew);//新建
    		mFile.add(miOpen);//打开
    		mFile.add(miSave);//保存
    		mFile.addSeparator();//分割条
    		mFile.add(miFont);//字体与颜色菜单
    		mFile.addSeparator();//分割条
    		mFile.add(miQuit);//退出		
    		mb.add(mFile); //将"文件"菜单添加到菜单栏上
    	}
    	
    	public void dealEvent(){
    		jButton2.addActionListener(this);
    		jButton1.addActionListener(this);
    		miFont.addActionListener(this);
    		miNew.addActionListener(this);
    		miOpen.addActionListener(this);
    		miSave.addActionListener(this);
    		miQuit.addActionListener(this);
    	}
    	
    	public void luceneIn(){
    		lab2=new JLabel("文件目录:");
    		lab2.setBounds(20,38,70,30);
    		field2=new JTextField(30);
    		field2.setBounds(90, 38, 120, 30);
    		jButton2=new JButton("...");
    		jButton2.setBounds(220,38,60,30);
    		lab1 = new JLabel("检索关键字:");
    		lab1.setBounds(310, 35, 90, 40);
    		field1=new JTextField("请输入检索关键字:",30);
    		field1.setBounds(400, 38, 200,30);
    		jButton1=new JButton("检索");
    		jButton1.setBounds(610,38,80,30);
    		topPane.add(lab1);
    		topPane.add(lab2);
    		topPane.add(field1);
    		topPane.add(field2);
    		topPane.add(jButton1);
    		topPane.add(jButton2);
    		jfc = new JFileChooser();
    		jfc.setCurrentDirectory(new File("d://"));// 文件选择器的初始目录定为d盘
    	}
    	
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if (e.getActionCommand()=="...") {
    			jfc.setFileSelectionMode(1);// 设定只能选择到文件夹 
    			int state = jfc.showOpenDialog(null);// 此句是打开文件选择器界面的触发语句  
                if (state == 1) {  
                    return;
                } else {  
                    File f = jfc.getSelectedFile();// f为选择到的目录
                    field2.setText(f.getAbsolutePath());
                    try {
    					LuceneIndex.createIndex(f.getAbsolutePath());//打开目录时,开始创建lucene索引
    				} catch (Exception e1) {
    					e1.printStackTrace();
    					JOptionPane.showMessageDialog(null,"构建索引库异常!");
    				}
                }  
    		}else if (e.getActionCommand()=="检索") {
    			tArea.setText("");
    			String searchName= field1.getText();
    			try {
    				 Map<String, String> respContents= LuceneIndex.searchIndex(searchName);//查询索引
    				if (respContents.isEmpty()) {
    					tArea.setText("未检索到文本内容");
    				}else{
    					StringBuilder sb=new StringBuilder();
    					 Set<Map.Entry<String, String>> entryseSet=respContents.entrySet();
    					 sb.append("检索到的文件总数:"+respContents.size()+"\n");
    					 sb.append("-------------------------------------分隔符-------------------------------------------\n\n");
    					 for (Map.Entry<String, String> entry:entryseSet) {
    						sb.append("所属文件:"+entry.getKey()+"\n"+"文件内容:\n"+entry.getValue()+"\n");
    						sb.append("-------------------------------------分隔符-------------------------------------------\n\n");
    					}
    					tArea.setText(sb.toString());
    					Highlighter highLighter = tArea.getHighlighter();
    					String text=tArea.getText();
    					DefaultHighlighter.DefaultHighlightPainter p = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
    					int pos = 0;
    			        while ((pos = text.indexOf(searchName, pos)) >= 0){
    			            try {
    			                highLighter.addHighlight(pos, pos + searchName.length(), p);
    			                pos += searchName.length();
    			            }catch (BadLocationException e2) {
    			                e2.printStackTrace();
    			            }
    			        }
    				}
    			} catch (Exception e1) {
    				e1.printStackTrace();
    				JOptionPane.showMessageDialog(null,"检索异常!");
    			}
    		}else if (e.getActionCommand()=="字体与颜色(F)...") {
    			TestJComboBox frm=new TestJComboBox("字体选择");
    			frm.setVisible(true);
    		}else if (e.getActionCommand()=="新建(N)") {
    			tArea.setText("");
    		}else if (e.getActionCommand()=="退出(X)") {
    			if (tArea.getText().length()>0) {
    				int result = JOptionPane.showConfirmDialog(null, "是否保存当前编辑过的文件?", "是", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
    				if (result==JOptionPane.YES_OPTION) {
    					FileDialog fd = new FileDialog(this,"保存", FileDialog.SAVE);
    					writeTxtFile(fd);
    				}
    			}
    			this.dispose();
    		}else if(e.getActionCommand()=="打开(O)..."){
    			FileDialog open = new FileDialog(this, "打开文件", FileDialog.LOAD); 
    			open.setVisible(true); 
    			String filePath = open.getDirectory() + open.getFile();
    			if (filePath != null) {
    				String fileContent="";
    				 if (filePath.toLowerCase().endsWith("ppt") || filePath.toLowerCase().endsWith("pptx")) {
    					  try {
    						fileContent=PPTParse.pptParse(filePath);
    					} catch (Exception e1) {
    						e1.printStackTrace();
    					}
    				  }else if (filePath.toLowerCase().endsWith("xls") || filePath.toLowerCase().endsWith("xlsx")) {
    					fileContent=ExcelParse.parseFile(filePath);
    				 }else if (filePath.toLowerCase().endsWith("pdf")) {
    					fileContent=PDFParse.parsePDF(filePath);
    				 }else if (filePath.toLowerCase().endsWith("doc") || filePath.toLowerCase().endsWith("docx")) {
    					fileContent=WordParse.parseFile(filePath);
    				 }else{
    					 fileContent= readTxtFile(filePath);
    				 }
    				tArea.setText(fileContent);
    			} 
    		}else if(e.getActionCommand()=="保存(S)"){
    			FileDialog fd = new FileDialog(this,"保存", FileDialog.SAVE);
    			writeTxtFile(fd);
    		}
    	}
    	
    	public void writeTxtFile(FileDialog fd){
    		fd.setVisible(true);
    		try {
    			FileOutputStream out = new FileOutputStream(fd.getDirectory() + fd.getFile()+".txt");
    	        Object jtext;
    	        String str =tArea.getText();
    	        out.write(str.getBytes());
    	        out.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public String readTxtFile(String filePath){
            try {
                    String encoding="UTF-8";
                    StringBuffer sBuffer=new StringBuffer();
                    File file=new File(filePath);
                    if(file.isFile() && file.exists()){ //判断文件是否存在
                        InputStreamReader read = new InputStreamReader(
                        new FileInputStream(file),encoding);//考虑到编码格式
                        BufferedReader bufferedReader = new BufferedReader(read);
                        String lineTxt = null;
                        while((lineTxt = bufferedReader.readLine()) != null){
                            sBuffer.append(lineTxt+"\n");
                        }
                        read.close();
                        return sBuffer.toString();
            }else{
                System.out.println("找不到指定的文件");
            }
            } catch (Exception e) {
                System.out.println("读取文件内容出错");
                e.printStackTrace();
            }
            return "";
        }
    	
    	public static void main(String[] args) {
    		 LuceneJFrame lFrame= new LuceneJFrame("全文检索");
    	}
    }
    

    有问题可以私信或者在评论区留言。写作不易,既然来了,不妨点个关注,点个赞吧!!!

    展开全文
  • sear全文检索

    2012-03-11 21:28:01
    实现本地网络的关键字 全文检索,sear全文检索
  • Markdown 全文检索

    2021-06-13 19:00:09
    1、Markdown 全文检索本地化实现方式 我个人的所有的笔记全部都是用 Markdown 来记录的,有一个文件夹用来存放所有的笔记。我不太喜欢那些在线的应用,我自己的习惯是把笔记保存在本地,然后用 Typora 来编辑。平常...

    1、Markdown 全文检索本地化实现方式

    我个人的所有的笔记全部都是用 Markdown 来记录的,有一个文件夹用来存放所有的笔记。我不太喜欢那些在线的应用,我自己的习惯是把笔记保存在本地,然后用 Typora 来编辑。平常会使用坚果云来云同步,但是一直找不到合适的全文检索工具。

    全文检索是:搜索文件的时候可以直接搜索某一个文件中的内容,而不仅是搜索文件名。我认为这个功能非常重要,因为有时候找某一篇笔记的时候,只记得一个大概的内容,而不确定在哪个文件中。

    找了很多的应用感觉都没那么顺手。我还是比较喜欢独立的应用,可以完全由我掌控。期间我试过为知笔记、有道云笔记、坚果云Markdown 等工具,但是用起来都感觉不太好,做的限制太多了。最终突然灵机一动,想到了 VScode 里的代码检索功能。然后试了一下,直呼真香,非常方便,而且自主性非常高。

    2、操作步骤

    1. 打开 VScode;

    2. 点击左上角的”文件“,选择”打开文件夹“,之后选择你的笔记文件夹即可;

      2o0KFH.png
      图:在VScode中打开文件夹
    3. 打开文件夹后效果如下图所示:

      2o0Ym8.png
      图:打开文件夹后效果
    4. 点击左侧的搜索键;

      2o0Dlq.png
      图:左侧的搜索
    5. 然后输入便可全文检索啦!

      2o0WtJ.png
      图:搜索结果测试

    3、总结

    本文实现了对于 Markdown 文件全文检索的本地化实现方式,使用 VScode 里的代码检索功能完成,方便快捷,自由度高。

    展开全文
  • 基于Lucene的全文检索系统,对本地文件的全文检索,方便搜索自己的文档
  • 基于elasticSearch做的全文检索,这是详细设计文档。包括结构化数据的检索,非结构化数据(文档类,如word,pdf等)检索。结构化数据,基于logstash导入。非结构化(文档),可以通过接口,本地扫描/远程扫描进入ES...
  • Lucene全文检索(一)

    2021-01-07 14:49:43
    Lucene实现全文检索的流程 创建索引 获得文档 原始文档:要基于那些数据来进行搜索,那么这些数据就是原始文档。 搜索引擎:使用爬虫获得原始文档 站内搜索:数据库中的数据。 本地搜索:直接使用io流读取磁盘上的...
  • 局域网全文检索软件

    千次阅读 2018-01-07 23:25:15
    日常有很多事务性工作,涉及大量文档或模板,而工作原因通常一个人所使用的文档会分布在局域网内各个电脑上,渐渐查找文档成了很头疼的问题,一来多数搜索方式只支持文件名搜索,二来这些搜索方式只支持本地检索,...

    前言

    由于所在单位的工作性质,日常有很多事务性工作,涉及大量文档或模板,而工作原因通常一个人所使用的文档会分布在局域网内各个电脑上,渐渐查找文档成了很头疼的问题,一来多数搜索方式只支持文件名搜索,二来这些搜索方式只支持本地检索,因而找文档时需要挨个电脑上重复查找,有时需要不断回想文件名,或者询问他人,影响工作效率。因而开发出该软件用以辅助办公(其实是单位另一个项目的子部分简化而来的)。

    一、     简介

    该软件基于lucene的全文索引引擎和pangu开源分词系统构建全文索引模块对本地多个文件夹内的文档进行全文索引,同时基于UDP组播协议完成局域网P2P文件查询请求以及利用同步TCP完成点对点结果发送以及文件请求和传输。UI基于.net框架和DevExpress控件集。

    主要功能:

    1、  多路径全文索引

    2、  局域网内对等节点全文检索

    3、  局域网检索结果文件请求与传输

    4、  多线程索引建立

    二、     使用说明

    1、  设置索引存储路径

    该路径为全文检索引擎lucene存储倒排索引分段文件的地方,可以拖动到窗口设置。

    2、  设置索引文件夹

    该文件夹为需要检索的文件所在路径,可以勾选递归子目录对子文件夹进行完整的索引。

    3、  点击左上角的新建索引,等待软件的索引建立,如果文件较多,可能耗时较长,尤其word和pdf文档耗时较多,可按照一个word、pdf文档30s,txt文档1s/1MB进行估算。

    4、  索引建立完成会弹出对话框提示,然后就可以在检索内容里输入要检索的关键词进行检索,也可以输入一句话,或者用空格隔开关键词,默认关键词是或的关系进行查找。

    5、  可以勾选左侧的搜索选项进行搜索范围的设定,搜索结果中的标题点击后可以打开对应的文档,如果文档是远程节点上的,可以弹出对话框提示是否需要保持,如果需要则选择路径,否则下载到临时文件夹内并打开。

    三、     源码结构介绍

    基础和通用类位于Common文件夹内,FullTextIndex完成全文检索的基本功能,NetWork提供了网络访问的基本功能,SQLite提供sqlite数据库的简单封装,Wrapper对全文检索、网络访问和数据库操作提供进一步的功能封装,并和UI交互,Main为主界面,ResultItem为自定义控件,封装了检索结果的显示以及和主界面的交互。

    (1)、Common文件夹介绍

    1、  其中GlobalVar集中管理了上层类会通用的只读变量,应用get访问器保证只读。

    2、  CommMethod类提供了上层类通用与功能无关的几个方法。

    3、  INIClass类提供了静态方法完成配置文件的读写。

    4、  MessageEventArgs类简单封装了本项目中用到的事件通知用到的事件消息。

    5、  CommObj文件提供了几个项目中通用的类的封装。

    (2)、FullTextIndex文件夹介绍

    1、Index类封装了Lucene.Net.Index.IndexWriter的一些基本操作,包括缓存的设置,索引的建立,对关键词的查询。

    2、TDocs类封装了文档对象,作为全文检索的基本单元,包含几个Field信息。

    (3)、NetWork文件夹介绍

    1、NetObject主要提供了用于封装UDP数据包的MultiCastObject类,用于文件请求信息的FileRequestObject类,和本地节点用于存储请求文件保存地址信息的类FileWaitObject。

    2、NetClass类初始化后会建立三个线程,分别用于接收UDP组播信息、监听并接收TCP字符串、以及监听并接收TCP文件传输,并在得到相应信息后以事件通知上层类NetOpt。

    (4)、SQLite文件夹介绍

    该文件夹内的类来源为SQLITE官方的Demo,主要封装了SQLite的操作,这里并不深入介绍。

    (5)、Wrapper文件夹介绍

    1、NetOpt类在NetClass类基础上进一步封装,对接收消息的事件进行响应,同时完成UI界面传入的数据发送请求,包括搜索请求和文件请求,以及对远程节点请求的响应。

    2、IndexOpt类在Index类基础上封装了对新建索引和检索的处理,连接了UI层和底层索引引擎。

    3、SQLiteCon类提供了基本的SQLite数据库操作如新建、插入、修改、删除等的简单访问方法。

    (6)、ResultItemCon自定义控件

    该控件提供对单条检索结果的标题、摘要显示,以及响应单击标题操作获取文件。

    其他

    源码地址

    http://download.csdn.net/download/atp1992/10193523

    软件地址:

    http://download.csdn.net/download/atp1992/10193522

    原作相关链接:

    http://www.straka.cn/blog/lanfulltextindexshare

    展开全文
  • 使用lucene技术,实现android的本地文档资源的全文检索功能,并实现关键字高亮
  • 我使用的maven添加的jar包。maven中的pom.xml中添加lucene的jar包的方法是:  Xml代码  project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=... xsi:schemaLocation=
  • 该软件基于lucene的全文索引引擎和pangu开源分词系统构建全文索引模块对本地多个文件夹内的文档进行全文索引,同时基于UDP组播协议完成局域网P2P文件查询请求以及利用同步TCP完成点对点结果发送以及文件请求和传输。...
  • 本文主要是学习oracle text 对服务器本地文件进行检索的学习笔记,主要参考oracle全文检索这个电子书和网上的一些例子。 首先将DBA权限赋予你的登录账号 begin ctx_ddl.create_preference ('my_datastore_...
  • 网站全文检索--Solr

    2017-05-03 20:25:28
    做CMS管理系统时,配置好模版(jetbrick-template),调用数据库取数据,一个页面上配置了多个数据源,会多...还有一个场景网站搜索时(全文检索),如果去查询数据库,当表中内容过大时会搜索延迟、无法响应等问题。 使
  • 该软件基于lucene的全文索引引擎和pangu开源分词系统构建全文索引模块对本地多个文件夹内的文档进行全文索引,同时基于UDP组播协议完成局域网P2P文件查询请求以及利用同步TCP完成点对点结果发送以及文件请求和传输。...
  • Spring Boot结合Jest实现对ElasticSearch的全文检索,分词检索,分页,高亮关键词等,很简单很详细 前提:本地已配置好es,以及es中已经存在数据 1、数据格式及索引名称,可以es-head中看见 ![索引名称以及数据格式]...
  • Lucene全文检索之流程与增删改

    千次阅读 2020-02-20 20:05:53
    Lucene实现全文检索的流程 创建索引 获得文档 原始文档:要基于那些数据来进行搜索,那么这些数据就是原始文档。 搜索引擎:使用爬虫获得原始文档 站内搜索:数据库中的数据。 本地搜索:直接使用io流读取磁盘上的...
  • 导读:在 IM 场景的客户端需求上,基于本地数据的全文检索(Full-text search)扮演着重要的角色。本文具体来聊聊网易云信是如何实现全文检索的。文|李宁网易云信高级前端开发工程...
  • 用SQLite进行全文检索

    千次阅读 2016-12-23 11:06:56
    对于应用软件开发人员来说,...如,利用MySQL和PostgreSQL或者Sphinx和Lucene这样的独立软件进行本地执行。然而,这些要么用起来棘手,要么就过度了。  幸运的是,Google为SQLite贡献了一些资源以实现帮助。在版
  • 4.3 多个全文检索结果的合并  在完成了上述准备工作后,就可以在应用上设计实际的合并过程了。步骤如下:  1. 在某一城市的客户端发起了一个全文检索的业务查询请求。  2. 查询引擎根据“业务查询...
  • 本文内容来自恩师 以下正文... Lucene 1.创建索引  1)获得文档 ... 原始文档:要基于哪些数据来进行... 本机:直接使用io流读取本地磁盘上的数据  2)构建文档对象  对应每个原始文档创建一个Document对象 ...
  • 最近帮助同事处理了一个关于全文检索的问题,随手记录下来供以后参考。 问题一 某些Cabinet下的文件可以全文检索到,但某些Cabinet下的数据全文检索不成功。 新建了一个Docbase-AADCTM,并且安装配置了对应的Index...
  • 优点: 1.查询速度快 2.支持中文分词准备工作:安装es...配置 修改ip地址 4.docker run -dti --network=host --name=elasticsearch -v /home/python/elasticsearch-2.4.6/config(本地文件路径):/usr/share/el...
  • 本文转载自本人博客:我的博客地址 测试可以访问的 不可访问  ...因此放弃了这种方案,采用了单纯搜索本地文件的全文检索策略,全文检索方面有大名鼎鼎的Lucene,之所以没有添加Lucene进来,是因为L...
  • 毕业设计-全文检索系统-分布式版本 在单机版的基础上,使用Orleans 1.5.3框架和Redis 3.2.100 Windows ver实现分布式检索。 由于安全提示,packages.config的 原版本为5.6.4,如有问题可以改回原版本 需要注意:VS...
  • 首先编写代码前,要先把Elasticsearch环境搭建好(这个很简单,网上百度一大堆)。...第一步:编写连接本地Elasticsearch环境的代码 public static Client client=null; public static Client getClient(){ ...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 238
精华内容 95
关键字:

本地全文检索