@Service
public class SearcherNewServiceImpl
implements SearcherNewService {
private static final Logger LOGGER =
Logger.getLogger("search");
@Autowired
private AppletNewsDao
appletNewsDao;
private static final String []
QUERY_FIELD = { "name" , "pinyin" , "pinyinHead", "id"}; //
查询结果需要展示什么字段就加什么字段到这个数组中,如这次的需求是要显示id,则添加id到数组中。
private static IndexSearcher
indexSearcher = null;
private static IndexReader reader =
null;
private static final String REGEX_NO = "^[0-9]\\w*$";
private static final String REGEX_CHAR = "^[a-zA-Z]*";
private static final int RESULT_COUNT = 100000;
private static Directory ramdDrectory = new RAMDirectory();
private final Lock writerLock = new ReentrantLock();
private volatile IndexWriter writer = null;
private Analyzer analyzer = new Analyzer(){
@Override
public TokenStream tokenStream(
String fileName,
Reader reader) {
return new
SearchTokenizer(reader);
}
};
public IndexWriter getIndexWriter(Directory dir, IndexWriterConfig
config) {
if (null == dir) {
throw new IllegalArgumentException("Directory can not be
null.");
}
if (null == config) {
throw new IllegalArgumentException("IndexWriterConfig can not be
null.");
}
try {
if (null == writer) {
if (IndexWriter.isLocked(dir))
{
//throw new
LockObtainFailedException("Directory of index had been
locked.");
IndexWriter.unlock(dir);
}
writer = new IndexWriter(dir,
config);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return writer;
}
@Override
public void index() throws
CorruptIndexException,
LockObtainFailedException,
IOException {
LOGGER.info(" init search method
index() ");
List list = loadResources();
if (list == null || list.isEmpty())
return ;
IndexWriterConfig config = new
IndexWriterConfig(Version.LUCENE_36, analyzer);
try {
writerLock.lock();
getIndexWriter(ramdDrectory,
config);
writer.deleteAll();
Document doc = null;
String pinyin = null;
String pinyinHead = null;
for (AppletNews appleNews : list)
{
pinyin =
PinyinUtils.getChineseByPinYin(appleNews.getLetters()).toLowerCase();
pinyinHead =
PinyinUtils.getPinYinHeadChar(appleNews.getLetters()).toLowerCase();
doc = new Document();
doc.add(new Field(QUERY_FIELD[0],
appleNews.getLetters(), Field.Store.YES,
Field.Index.ANALYZED));//这里是设置相应的要模糊查询的字段 0是name
1是拼音 2是拼音首字母
3是在查询完成后要展示的字段,这次是id,值为查询结果的id
doc.add(new Field(QUERY_FIELD[1],
pinyin, Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field(QUERY_FIELD[2], pinyinHead,
Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field(QUERY_FIELD[3],
String.valueOf(appleNews.getId()), Field.Store.YES,
Field.Index.NOT_ANALYZED));
writer.addDocument(doc);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
writer.close();
writer = null;
writerLock.unlock();
}
}
@Override
public Object search(String
queryWord)
throws Exception {
JSONArray appletNewsList = new
JSONArray();
indexSearcher =
getIndexSearcher(reader);
if (indexSearcher == null) {
return appletNewsList;
}
Query query = null;
PhraseQuery phrase = null;
PrefixQuery prefix = null;
BooleanQuery blquery = null;
QueryParser parser =
null;
MultiFieldQueryParser
multiParser = null;
TermQuery term = null;
String[] multiQueryField =
{QUERY_FIELD[0]};
if (queryWord.matches(REGEX_NO))
{
queryWord =
queryWord.toLowerCase();
// code搜索
phrase = new PhraseQuery();
phrase.setSlop(0);
for (int i = 0; i <
queryWord.length(); i++) {
phrase.add(new Term(QUERY_FIELD[2],
Character.toString(queryWord.charAt(i))));
}
query = phrase;
} else if
(queryWord.matches(REGEX_CHAR)) {
// 拼音搜索
prefix = new PrefixQuery(new
Term(QUERY_FIELD[1], queryWord.toLowerCase()));
query = new WildcardQuery(new
Term(QUERY_FIELD[2], queryWord.toLowerCase() + "*"));
term = new TermQuery(new
Term(QUERY_FIELD[0], queryWord.toLowerCase()));
blquery = new BooleanQuery();
blquery.add(prefix,
Occur.SHOULD);
blquery.add(query,
Occur.SHOULD);
blquery.add(term,
Occur.SHOULD);
query = blquery;
} else {
multiParser = new
MultiFieldQueryParser(Version.LUCENE_36, multiQueryField,
analyzer);
parser = multiParser;
parser.setDefaultOperator(QueryParser.Operator.AND);
query =
parser.parse(QueryParser.escape(queryWord));
}
LOGGER.info("query param is : " +
query.toString());
// start time
TopScoreDocCollector collector =
TopScoreDocCollector.create(RESULT_COUNT, false);
long start = new
Date().getTime();
indexSearcher.search(query,
collector);
ScoreDoc[] hits =
collector.topDocs().scoreDocs;
JSONObject appletNews =
null;
for (ScoreDoc scoreDoc :
hits) {
Document doc =
indexSearcher.doc(scoreDoc.doc);
appletNews = new JSONObject();
appletNews.put(QUERY_FIELD[0],
doc.get(QUERY_FIELD[0]));
appletNews.put(QUERY_FIELD[1],
doc.get(QUERY_FIELD[1]));
appletNews.put(QUERY_FIELD[2],
doc.get(QUERY_FIELD[2]));
appletNews.put(QUERY_FIELD[3],
doc.get(QUERY_FIELD[3]));//数组第四个位置是id,如果添加的在上面的数组中设置了别的字段,则按照上面的格式在这里添加相应的结果。
appletNewsList.add(appletNews);
}
// end time
long end = new
Date().getTime();
LOGGER.info(
"\nFound " + collector.getTotalHits()
+ " document(s) (in "
+ (end - start) + "
millindexSearchereconds) that matched query '"
+ queryWord + "':"
);
return appletNewsList;
}
private IndexSearcher getIndexSearcher(
IndexReader reader){
try {
if (reader == null) {
reader =
IndexReader.open(ramdDrectory);
} else {
//如果当前reader在打开期间index发生改变,则打开并返回一个新的IndexReader,否则返回null
IndexReader ir = IndexReader.openIfChanged(reader);
if (ir !=
null) {
reader.close();
reader = ir;
}
}
return new IndexSearcher(reader);
}catch(Exception e) {
e.printStackTrace();
}
return null;
//发生异常则返回null
}
@Override
public void loadFundInfo() {}
//这个方法是用来查询出所有的要模糊查询的对象,模糊查询是在这个方法查询出的所有对象中获取匹配的对象
public List loadResources() {
List fundInfoList =
appletNewsDao.selectAll();
return fundInfoList;
}
接下来是调用的方法:
@SuppressWarnings("unchecked")
@Override
public Result seachList(String
letter) {
Result result = new Result();
if(null == letter ||
"".equals(letter)){
result.setCode(Constance.RESPONSE_INNER_ERROR);
result.setMsg("请求参数不可为空");
return result;
}
List>
list = new ArrayList>();
Map map = null;
try {
JSONArray letterList = (JSONArray)
searcherNewService.search(letter);
Iterator iterator =
letterList.iterator();
while (iterator.hasNext()) {
JSONObject json =
iterator.next();
map = new HashMap();
map.put("letters",
json.getString("name"));
map.put("id",
json.getString("id"));
list.add(map);
}
} catch (Exception e) {
e.printStackTrace();
}
if(null == list || list.size() <
1){
result.setCode(Constance.RESPONSE_INNER_ERROR);
result.setMsg("没有可查询的记录");
}{
result.setCode(Constance.RESPONSE_SUCCESS);
result.setMsg("查询成功");
result.setData(list);
}
return result;
}