`

智能查询功能lucene使用情况及遇到的问题

阅读更多
[color=orange][/color]系统智能查询功能lucene使用情况及遇到的问题
根据客户反映我们要实现的搜索功能。
【范例】
• 【自然语查询】输入「百草」,可以查到「百草路」
• 【同音字查询】输入「白超路」,可以查到「百草路」
第一. 自然语句查询。
这是lucene大众化的搜索功能,但是单纯使用lucene官方包内的提供中文分词器,不能很好的实现我们需要的功能。
但是我通过使用Google IKAnalyzer的一个开源项目,目前已经利用这个分词器基本上将这个功能实现。
IKAnalyzer是一个很好的开源中文分词器,拆分方式例如:

文本原文1:
IKAnalyzer 是一个开源的,基于java 语言开发的轻量级的中文分词工具包。从2006 年12月推出1.0 版开始, IKAnalyzer 已经推出了3 个大版本。
分词结果:
ikanalyzer | 是| 一个| 一| 个| 开源| 的| 基于| java | 语言| 开发| 的| 轻量
级| 量级| 的| 中文| 分词| 工具包| 工具| 从| 2006 | 年| 12 | 月| 推出| 1.0
| 版| 开始| ikanalyzer | 已经| 推出| 出了| 3 | 个大| 个| 版本

IKAnalyzer的是比较智能按照我们的读音进行拆分。

上面的例子当用户输入:一个字 “是” 或是两个字 “开源”  搜索就可以检索出上面的记录  。但是如果输入的是“开”  搜索不能检索出上面记录。
问题根源在于:“开”是和“开源”拆分在一起的,并不是一个单独的搜索关键字。

关于这里lucene 的使用:
1. 导入lucene-core-3.0.1.jar  和IKAnalyzer3.2.3Stable.jar
2. 我改造了的一个demo可以直接运行: IKAnalyzerDemo.Jar(里面代码都有注释)

第二. 同音字查询
     同音字查询没有什么进展,首先网上没有这方面的思路介绍,更没有拼音的拆分器。
总体最可行的方案有几种,
     1根据拼音足组合字词
           即:用户输入baicao  我们可以组合出  |百草|白草败草|拜槽|等可能的词来
               这个需要建立以拼音——字符库
              


例:
ce=册侧策测厕恻側冊厠墄嫧帻幘廁惻憡拺敇柵栅測畟笧筞筴箣簎粣荝萗萴蓛赦齰刂
cen=参岑涔參叄叅嵾梣汵硶穇笒篸膥
ceng=曾层蹭噌僧增層嶒橧竲繒缯驓
当然我们可以根据我们库中的内容建立不用把搜有的字都建立进去。

这样我们通过解析解析拼音组合出响应的词句来,再通过lucene到索引文件中搜索。

实现难度:
拼词的实现难度很大,怎样拼出最合适的词来是关键(拼出过多的组合来在查询的时候很浪费资源并且效率上也需要有好的解决方案)。
3. 索引文件建立是建立出响应的全拼 单个字的拼音
例如:java 语言开发  这句话
我们建立索引时可以这样:java 语言开发  java  yu  yan  kai  fa  javayuyankaifa
这样可以通过两种方式去搜索
1)。IKAnalyzer中文分词器它会把语句拆分成:
Java| 语言|开发|  java | yu | yan | kai | fa | javayuyankaifa|
Lucene中所有的分词器凡是遇到空格道义一个分词点

这样用户输入 “yu “ 或是“yan”或是“javayuyankaifa|
”可以搜出响应的内容
但是输入”javayuyan”便不能搜出响应的记录  因为分词中没有“javayuyan”这个词。
2)。解决输入“javayuyan“可以在使用WildcardQuery这个搜索器。
   搜索器分为五种
       布尔操作符  
域搜索(Field Search)
通配符搜索(Wildcard Search)
模糊查询
范围搜索(Range Search)
我们使用通配符搜索(Wildcard Search)在输入的内容中格式化为“* javayuyan*”就可以匹配到“javayuyankaifa“
但是如果用户输错了拼音或是输入的是谐音那就什么也查不到了
3)。对于输入的是谐音汉字 :可以把谐音汉字拆分成带空格的 例如输入“白抄录”
  拼音转出来时“bai  chao  lu”这样可以”bai” 和“lu”两个词时能搜到相关带“bai”和”cao”的。
但是如果输入的三个字三个都是谐音  那就又完啦!!!

我想到的就是这两种方案

总体来说第二种方案实现起来难度不大但是bug太多。并且要分几次去搜索效能降低太厉害

第一种方案实现难度大但是是现在输入法和搜索引擎公司采用的方式。他们都对搜索频率大的字词特做记录  像搜狗我们经常打的字他会最先出现。实现好了这肯定是最好的方式。



写的太仓促没检查  错字错句模糊匹配啦!!!!!!


Lucene相关资料
Lucene搜索使用
http://www.chedong.com/tech/lucene.html
中文分析器
http://www.cnblogs.com/wuxh/articles/77870.html

应经实现的测试类:
package test.insta;

/**
* IK Analyzer Demo
* @param args
*/
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory; // 引用IKAnalyzer3.0的类
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

/**
* @author 同串比较
*/
public class IKAnalyzerDemo {
public static void main(String[] args) {
// Lucene Document的域名
String fieldName = "text";
// 检索内容
String text = "IK Analyzer bai cao lu wang jia da dao  baicaoluwangjiadadao  搜索王贾大道是一个结合词典分词和文法分词的中文分词开源工具包。它使用了全新的正向迭代最细粒度切分算法。";
// 实例化IKAnalyzer分词器
Analyzer analyzer = new IKAnalyzer();
Directory directory = null;
IndexWriter iwriter = null;
IndexSearcher isearcher = null;
try {
// 建立内存索引对象
directory = new RAMDirectory();
iwriter = new IndexWriter(directory, analyzer, true,
IndexWriter.MaxFieldLength.LIMITED);
Document doc = new Document();
doc.add(new Field(fieldName, text, Field.Store.YES,
Field.Index.ANALYZED));
iwriter.addDocument(doc);
iwriter.close();
// 实例化搜索器
isearcher = new IndexSearcher(directory);
// 在索引器中使用IKSimilarity相似度评估器
isearcher.setSimilarity(new IKSimilarity());
String keyword = "是";
keyword=dissect(keyword);
// 使用IKQueryParser查询分析器构造Query对象
Query query = IKQueryParser.parse(fieldName, keyword);
// 搜索相似度最高的5条记录
TopDocs topDocs = isearcher.search(query, 5);
System.out.println("命中:" + topDocs.totalHits);
// 输出结果
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (int i = 0; i < topDocs.totalHits; i++) {
Document targetDoc = isearcher.doc(scoreDocs[i].doc);
System.out.println("内容:" + targetDoc.toString());
}
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (LockObtainFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isearcher != null) {
try {
isearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (directory != null) {
try {
directory.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


protected static String dissect(String input) {

StringBuilder sb = new StringBuilder();
TokenStream ts = null;
try {
HashSet stopWords = new HashSet();
IKAnalyzer analyzer = new IKAnalyzer();
ts = analyzer.tokenStream("", new StringReader(input));
sb.setLength(0);
while (ts.incrementToken()) {
sb.append("   ");
sb.append(
((TermAttribute) ts.getAttribute(TermAttribute.class))
.term()).append("  ");
;
}

if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();

} catch (Exception e) {

e.printStackTrace();
return input;
} finally {
if (ts != null) {
try {
ts.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

}
}


通配符测试:
package test;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.WildcardQuery;

public class WildcardQueryTest {
public static void main(String[] args) throws Exception {
  //生成Document对象,下同
  Document doc1 = new Document();
  Document doc2 = new Document();
  Document doc3 = new Document();
  Document doc4 = new Document();

  //添加“content”字段的内容,下同
  doc1.add(new Field("content", "whatever ni hao",Field.Store.YES,
  Field.Index.ANALYZED));
  //添加“title”字段的内容,下同
  doc1.add(new Field("title", "doc1 ",Field.Store.YES,
Field.Index.ANALYZED));
 
//添加“content”字段的内容,下同
  doc2.add(new Field("content", "whatever  nihao ",Field.Store.YES,
Field.Index.ANALYZED));
  //添加“title”字段的内容,下同
  doc2.add(new Field("title", "doc2",Field.Store.YES,
Field.Index.ANALYZED));
//添加“content”字段的内容,下同
  doc3.add(new Field("content", "whatever nihaoa ",Field.Store.YES,
Field.Index.ANALYZED));
  //添加“title”字段的内容,下同
  doc3.add(new Field("title", "doc3",Field.Store.YES,
Field.Index.ANALYZED));
//添加“content”字段的内容,下同
  doc4.add(new Field("content", "whatever wonihaoma",Field.Store.YES,
Field.Index.ANALYZED));
  //添加“title”字段的内容,下同
  doc4.add(new Field("title", "doc4",Field.Store.YES,
Field.Index.ANALYZED));
 
  //生成索引书写器
  IndexWriter writer = new IndexWriter("c:\\index",
    new StandardAnalyzer(), true);
  //将文档对象添加到索引中
  writer.addDocument(doc1);
  writer.addDocument(doc2);
  writer.addDocument(doc3);
  writer.addDocument(doc4);
  //关闭索引书写器
  writer.close();

    //生成索引书写器
  IndexSearcher searcher = new IndexSearcher("c:\\index");
  //构造词条
  Term word1 = new Term("content", "*nihao");
  Term word2 = new Term("content", "nihao");
  Term word3 = new Term("content", "nihao?");
  Term word4 = new Term("content", "nihao*");
  //生成WildcardQuery对象,初始化为null
  WildcardQuery query = null;
  //用于保存检索结果
  Hits hits = null;
 
  query = new WildcardQuery(word1);
  //开始第一次检索,并返回检索结果
  hits = searcher.search(query);
  //输出检索结果的相关信息
  printResult(hits, "*nihao");
 
  query = new WildcardQuery(word2);
  //开始第二次检索,并返回检索结果
  hits = searcher.search(query);
  //输出检索结果的相关信息
  printResult(hits, "nihao");
 
  query = new WildcardQuery(word3);
  //开始第三次检索,并返回检索结果
  hits = searcher.search(query);
  //输出检索结果的相关信息
  printResult(hits, "nihao?");
 
  query = new WildcardQuery(word4);
  //开始第四次检索,并返回检索结果
  hits = searcher.search(query);
  //输出检索结果的相关信息
  printResult(hits, "nihao*");
}

public static void printResult(Hits hits, String key) throws Exception
  {System.out.println("查找 \"" + key + "\" :");
  if (hits != null) {
   if (hits.length() == 0) {
    System.out.println("没有找到任何结果");
    System.out.println();
   } else {
    System.out.print("找到");
    for (int i = 0; i < hits.length(); i++) {
     //取得文档对象
     Document d = hits.doc(i);
     //取得“title”字段的内容
     String dname = d.get("title");
     System.out.print(dname + "   ");
    }
    System.out.println();
    System.out.println();
   }
  }
}
}

[color=red]65443941这是我们的q  q 群 技术讨论社区。flex java gis (arcgis googlemap)技术讨论,数据库优化,数据模型设计,系统架构设计。基于uml的需求分析系统设计等等,欢迎加入。
分享到:
评论

相关推荐

    lucene高级智能查询小案例

    本篇将通过一个小案例,探讨Lucene在高级智能查询中的应用,尽管案例中可能存在一些小瑕疵,但主要的功能与思路已得以体现。 Lucene的核心在于其建立倒排索引的能力,这种索引结构使得快速匹配大量文档成为可能。...

    lucene-7.2

    faadkfsdfasdkfaksdkfadskfksdkf"看似是一串无意义的字符,但我们可以从中推测讨论的内容可能涉及到 Lucene 在实际应用中的使用情况,例如与其他技术(如 kdkafdsf...)的集成,或者是在解决某些问题时遇到的困难。...

    ikanalyzer中文分词支持lucene7.1.0

    ikanalyzer中文分词支持lucene7.1.0是一个针对Lucene搜索引擎的中文分词扩展,由林良益先生开发,旨在提供高效、精准的中文词汇拆解功能。Lucene是一个开源全文检索库,它提供了索引和搜索文本的强大工具。然而,...

    lucene的IKAnalyzer以及兼容4.3

    在使用IKAnalyzer与Lucene 4.3结合时,可能会遇到一些兼容性问题,主要是由于版本更新带来的API变化。例如,Lucene的某些类、方法或接口可能在新版本中被废弃或调整,导致旧版的IKAnalyzer无法直接运行。为了解决...

    Lucene全文搜索 分组,精确查找,模糊查找

    在实际应用中,我们可能会遇到中文分词的问题。这时,IKAnalyzer就派上了用场。它是一款针对中文的分词工具,支持扩展词典和智能分析。在Lucene中,我们可以使用IKAnalyzer作为Analyzer,它会自动对输入的中文文本...

    lucene5.5做同义词分析器

    例如,"汽车"和"轿车"在很多情况下可以互换使用,如果一个查询使用了"汽车",而文档中使用了"轿车",同义词分析器就能确保这两个词之间的关联性不会被忽略。 在Lucene 5.5中,我们可以通过自定义Analyzer来实现同义...

    基于Lucene的Web搜索引擎的研究

    尽管Lucene在Web搜索引擎中有广泛的应用,但仍面临如大数据量处理、用户个性化需求、实时性、准确性等问题。未来的研究可能集中在如何更好地利用机器学习和人工智能技术来提升搜索引擎的性能和用户体验,例如,引入...

    Android系统基于Lucene的SD卡 搜索

    Lucene的核心功能包括分词、建立倒排索引、查询解析和结果排序。在Android中使用Lucene,可以为应用程序添加强大的本地搜索能力。 **Android环境**:Android是Google主导的开源移动操作系统,主要运行在智能手机和...

    搜索篇:Struts、Lucene的Web实例

    6. **错误处理和调试**:讲解在实际开发中可能遇到的问题,以及如何调试和解决这些问题。 7. **实际案例分析**:通过具体的Web应用示例,展示Struts和Lucene结合的完整流程。 通过学习这个教程,开发者不仅可以掌握...

    Android 智能问答机器人的实现

    例如,我们可以使用Stanford NLP库进行分词和语义分析,使用Apache Lucene或Elasticsearch进行信息检索,使用TensorFlow或PyTorch进行深度学习模型的集成。 博客实例代码中的"zhy_robot_01"可能包含以下几个关键...

    基于Lucene和Heritrix技术搜索引擎的设计与实现.pdf

    本文旨在探讨基于Lucene和Heritrix技术的搜索引擎设计与实现方法,以期为构建高效、智能的搜索引擎系统提供参考。 #### 二、关键技术解析 **1. Lucene** Lucene是Apache软件基金会Jakarta项目组下的一个子项目,...

    基于ASP.Net和Lucene.Net开发的站内搜索引擎Demo源码+项目说明+sln解决方案.zip

    欢迎下载使用,若遇到问题请及时私信沟通,帮助解决。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,可直接作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高...

    solr6.x的IKAnalyzer配置智能分词

    Solr是Apache Lucene项目的一个开源搜索引擎服务器,它提供了全文检索、高级索引和搜索功能。IKAnalyzer是一款针对中文的开源分词器,它在处理中文词汇时表现优秀,尤其适用于搜索引擎和信息检索系统。在Solr中配置...

    全文检索lucence3.5+IKAnalzers3.5示例

    在实际项目中,你可能会遇到多线程索引、更新索引、删除索引等问题,Lucene 3.5对此都有很好的支持。同时,为了优化性能,可以考虑使用缓存、倒排索引压缩等技术。 总结,Lucene 3.5结合IKAnalyzer 3.5为开发者提供...

    JAVA技术与人工智能在搜索引擎上的应用

    - **强大的社区支持**:Java拥有庞大的开发者社区,这意味着在遇到问题时能够获得及时的帮助和支持。 - **丰富的库和工具**:Java生态系统中有许多成熟的库和工具可用于搜索引擎的开发,如Lucene等。 #### 三、人工...

Global site tag (gtag.js) - Google Analytics