package com.pera.suggestion;

import java.io.IOException;

import java.io.Reader;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.LowerCaseFilter;

import org.apache.lucene.analysis.StopFilter;

import org.apache.lucene.analysis.TokenStream;

import org.apache.lucene.analysis.standard.StandardFilter;

import org.apache.lucene.analysis.standard.StandardTokenizer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.IndexReader;

import org.apache.lucene.index.IndexWriter;

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.Sort;

import org.apache.lucene.search.TermQuery;

import org.apache.lucene.search.TopDocs;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.FSDirectory;

public class Sugesstion {

private static final String GRAMMED_WORDS_FIELD = "words";

private static final String SOURCE_WORD_FIELD = "sourceWord";

private static final String COUNT_FIELD = "count";

private static final String[] ENGLISH_STOP_WORDS = {

     "a", "an", "and", "are", "as", "at", "be", "but", "by",

     "for", "i", "if", "in", "into", "is",

     "no", "not", "of", "on", "or", "s", "such",

     "t", "that", "the", "their", "then", "there", "these",

     "they", "this", "to", "was", "will", "with"

     };

private final Directory autoCompleteDirectory;

private IndexReader autoCompleteReader;

private IndexSearcher autoCompleteSearcher;

public Sugesstion(String autoCompleteDir) throws IOException {

      this.autoCompleteDirectory = FSDirectory.getDirectory(autoCompleteDir,

        null);

reOpenReader();

     }

public List<String> suggestTermsFor(String term) throws IOException {

      // get the top 5 terms for query

      Query query = new TermQuery(new Term(GRAMMED_WORDS_FIELD, term));

      Sort sort = new Sort(COUNT_FIELD, true);

TopDocs docs = autoCompleteSearcher.search(query, null, 5, sort);

      List<String> suggestions = new ArrayList<String>();

      for (ScoreDoc doc : docs.scoreDocs) {

       suggestions.add(autoCompleteReader.document(doc.doc).get(

         SOURCE_WORD_FIELD));

      }

return suggestions;

     }

@SuppressWarnings("unchecked")

     public void reIndex(Directory sourceDirectory, String fieldToAutocomplete)

       throws CorruptIndexException, IOException {

      // build a dictionary (from the spell package)

      IndexReader sourceReader = IndexReader.open(sourceDirectory);

LuceneDictionary dict = new LuceneDictionary(sourceReader,

        fieldToAutocomplete);

// code from

      // org.apache.lucene.search.spell.SpellChecker.indexDictionary(

      // Dictionary)

      IndexReader.unlock(autoCompleteDirectory);

// use a custom analyzer so we can do EdgeNGramFiltering

      IndexWriter writer = new IndexWriter(autoCompleteDirectory,

      new Analyzer() {

       public TokenStream tokenStream(String fieldName,

         Reader reader) {

        TokenStream result = new StandardTokenizer(reader);

result = new StandardFilter(result);

        result = new LowerCaseFilter(result);

        result = new ISOLatin1AccentFilter(result);

        result = new StopFilter(result,

         ENGLISH_STOP_WORDS);

        result = new EdgeNGramTokenFilter(

         result, Side.FRONT,1, 20);

return result;

       }

      }, true);

writer.setMergeFactor(300);

      writer.setMaxBufferedDocs(150);

// go through every word, storing the original word (incl. n-grams)

      // and the number of times it occurs

      Map<String, Integer> wordsMap = new HashMap<String, Integer>();

Iterator<String> iter = (Iterator<String>) dict.getWordsIterator();

      while (iter.hasNext()) {

       String word = iter.next();

int len = word.length();

       if (len < 3) {

        continue; // too short we bail but "too long" is fine...

       }

if (wordsMap.containsKey(word)) {

        throw new IllegalStateException(

          "This should never happen in Lucene 2.3.2");

        // wordsMap.put(word, wordsMap.get(word) + 1);

       } else {

        // use the number of documents this word appears in

        wordsMap.put(word, sourceReader.docFreq(new Term(

          fieldToAutocomplete, word)));

       }

      }

for (String word : wordsMap.keySet()) {

       // ok index the word

       Document doc = new Document();

       doc.add(new Field(SOURCE_WORD_FIELD, word, Field.Store.YES,

         Field.Index.UN_TOKENIZED)); // orig term

       doc.add(new Field(GRAMMED_WORDS_FIELD, word, Field.Store.YES,

         Field.Index.TOKENIZED)); // grammed

       doc.add(new Field(COUNT_FIELD,

         Integer.toString(wordsMap.get(word)), Field.Store.NO,

         Field.Index.UN_TOKENIZED)); // count

writer.addDocument(doc);

      }

sourceReader.close();

// close writer

      writer.optimize();

      writer.close();

// re-open our reader

      reOpenReader();

     }

private void reOpenReader() throws CorruptIndexException, IOException {

      if (autoCompleteReader == null) {

       autoCompleteReader = IndexReader.open(autoCompleteDirectory);

      } else {

       autoCompleteReader.reopen();

      }

autoCompleteSearcher = new IndexSearcher(autoCompleteReader);

     }

public static void main(String[] args) throws Exception {

      Sugesstion autocomplete = new Sugesstion("/index/autocomplete");

// run this to re-index from the current index, shouldn't need to do

      // this very often

      // autocomplete.reIndex(FSDirectory.getDirectory("/index/live", null),

      // "content");

String term = "steve";

System.out.println(autocomplete.suggestTermsFor(term));

      // prints [steve, steven, stevens, stevenson, stevenage]

     }

}

Lucene 自动补全的更多相关文章

  1. ES系列十三、Elasticsearch Suggester API(自动补全)

    1.概念 1.补全api主要分为四类 Term Suggester(纠错补全,输入错误的情况下补全正确的单词) Phrase Suggester(自动补全短语,输入一个单词补全整个短语) Comple ...

  2. jQuery 邮箱下拉列表自动补全

    综述 我想大家一定见到过,在某个网站填写邮箱的时候,还没有填写完,就会出现一系列下拉列表,帮你自动补全邮箱的功能.现在我们就用jQuery来实现一下. 博主原创代码,如有代码写的不完善的地方还望大家多 ...

  3. eclipse自动补全的设置

    eclipse自动补全的设置   如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的 ...

  4. vim 添加php自动补全 并格式化代码

    自动补全,修改/etc/vimrc的配置 vim /etc/vimrc 添加: filetype plugin on autocmd FileType php set omnifunc=phpcomp ...

  5. Eclipse自动补全设置

    如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为ecl ...

  6. Autocomplete 自动补全(Webform实战篇)

    开篇语 因为项目中需要用到一个自动补全的功能,功能描述: 需求一:新增收件人的时候,自动下拉显示出数据库中所有的收件人信息(显示的信息包括:姓名-收件地址-联系方式) 需求二:选中一个值得时候,分别赋 ...

  7. eclipse自动补全的设置(自动提示)

      如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为e ...

  8. jQuery AutoComplete 自动补全

    jQuery.AutoComplete是一个基于jQuery的自动补全插件.借助于jQuery优秀的跨浏览器特性,可以兼容Chrome/IE/Firefox/Opera/Safari等多种浏览器. 特 ...

  9. Vim自动补全神器–YouCompleteMe

    一.简介 YouCompleteMe是Vim的自动补全插件,与同类插件相比,具有如下优势 1.基于语义补全 2.整合实现了多种插件 clang_complete.AutoComplPop .Super ...

随机推荐

  1. springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

    之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...

  2. nginx时间设置解析函数

    https://trac.nginx.org/nginx/browser/nginx/src/core/ngx_parse.c /* * Copyright (C) Igor Sysoev * Cop ...

  3. git > 2.3 实现同步盘的功能

    话不多说,简单粗暴 http://stackoverflow.com/questions/35643201/how-to-set-up-a-sychronous-directory-in-remote ...

  4. jboss规则引擎KIE Drools 6.3.0 Final 教程(3)

    在前2部教程中,介绍了如何在本地运行.drools文件以及使用stateless的方法访问远程repository上的规则. KIE Drools还提供了一种叫有状态-stateful的访问方式. 运 ...

  5. 剑指Offer——知识点储备-故障检测、性能调优与Java类加载机制

    剑指Offer--知识点储备-故障检测.性能调优与Java类加载机制 故障检测.性能调优 用什么工具可以查出内存泄露 (1)MerroyAnalyzer:一个功能丰富的java堆转储文件分析工具,可以 ...

  6. iOS网络基础

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51376048 本文出自:[openXu的博客] 常用类 get请求 post请求 NSURL ...

  7. Erlang递归列举目录下文件

    Erlang递归列举目录下文件(金庆的专栏)%%%-------------------------------------------------------------------%%% @aut ...

  8. Java学习之运算符使用注意的问题

    运算符使用注意的问题 运算符(掌握) (1)算术运算符 A:+,-,*,/,%,++,-- B:+的用法 a:加法 b:正号 c:字符串连接符 C:/和%的区别 数据做除法操作的时候,/取得是商,%取 ...

  9. UNIX环境高级编程——标准IO-实现查看所有用户

    #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h&g ...

  10. 最简单的基于DirectShow的示例:视频播放器

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...