专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » lucene搜索:Lucene.Net 2.3.1开发介绍 4、搜索( 2) »正文

lucene搜索:Lucene.Net 2.3.1开发介绍 4、搜索( 2)

来源: 发布时间:星期四, 2009年1月15日 浏览:21次 评论:0
  4.3 表达式

  用户搜索只会输入个或几个词也可能是句话输入语句是如何变成搜索条件篇已经略有提及

  4.3.1 观察表达式

  在研究表达式的前定要知道任何个Query都会对于个表达式不光可以通过Query构造表达式还可以通过拼接串构造这里说观察表达式是指用Query完成查询语句后思路方法输出Query表达式很简单是吧呵呵

  4.3.2 表达式和或非

  “和或非”让我想起上学时候学门电路 #先动手看看什么是和或非

代码 4.3.2.1
using ;
using .Collections.Generic;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using NUnit.Framework;
Test
{
  [TestFixture]
  public StandardAnalyzerCaseTest
  {
    /// <summary>
    /// 执行测试入口
    /// </summary>
    [Test]
    public void SearcherTest
    {
      Index;
      List<> list = List<> { "测试" };
      for ( i = 0; i < list.Count; i)
      {
        Console.WriteLine("搜索词:" + list[i]);
        Console.WriteLine("结果:");
        Searcher(list[i]);
        Console.WriteLine("-----------------------------------");
      }
    }
    /// <summary>
    /// 搜索
    /// </summary>
    /// <param name="query">搜索输入</param>
    private void Searcher( query)
    {
      Analyzer analyzer = StandardAnalyzer;
      IndexSearcher searcher = IndexSearcher("IndexDirectory");
      QueryParser parser = QueryParser("content", analyzer);
      Query query = parser.Parse(query);
      //输出我们要查看表达式
      Console.WriteLine(query.);
      Hits hits = searcher.Search(query);
      for ( i = 0; i < hits.Length; i)
      {
        Document doc = hits.Doc(i);
        Console.WriteLine(doc.Get("title"));
      }
    }
    /// <summary>
    /// 索引数据
    /// </summary>
    private void Index
    {
      Analyzer analyzer = StandardAnalyzer;
      IndexWriter writer = IndexWriter("IndexDirectory", analyzer, true);
      AddDocument(writer, "测试", @"测定是123123ab阿布");
      AddDocument(writer, "测试测", @"测试搜索真是不是 ");
      AddDocument(writer, "来测试", @"好好测试山");
      AddDocument(writer, "测试系统", @"测试样例");
      writer.Optimize;
      writer.Close;
    }
    /// <summary>
    /// 添加文档
    /// </summary>
    /// <param name="writer">维护文档管理器</param>
    /// <param name="title">标题</param>
    /// <param name="content">内容</param>
    /// <param name="tag">tag</param>
    /// <param name="boost">tagboost</param>
    void AddDocument(IndexWriter writer, title, content)
    {
      Document document = Document;
      document.Add( Field("title", title, Field.Store.YES, Field.Index.TOKENIZED));
      document.Add( Field("content", content, Field.Store.YES, Field.Index.TOKENIZED));
      writer.AddDocument(document);
    }
  }
}


  先准备好代码4.3.2.1OK现在测试结果输出:

  搜索词:测试

  结果:

  content:"测 试"

  测试系统

  来测试

  测试测

  -----------------------------------

  第 3行就是表达式这个表达式不知道是什么意思?输入了“测试”这两个字进行搜索如何会变成 “content:"测 试"”呢?可以看出“测试”中间空了个空格还多了个content“测试”中间有空格不难理解是分词器对它进行拆分结果至于content,这个需要把目光转到QueryParser类上去在构造QueryParser类时候就加了这么个参数这个是表面要搜索哪个字段为了验证这个想法现在把“测试”换成英文“ab”把content换成title.

  也就是替换以下两句:

List<> list = List<> { "ab" };     //在思路方法SearcherTest中
QueryParser parser = QueryParser("title", analyzer);   //在思路方法Searcher中


  现在再测试下:

  搜索词:ab

  结果:

  title:ab

  -----------------------------------

  看到了果然是这样

  现在把查询字段还是换成content,然后把关键字换成“真是”

  搜索词:真是

  结果:

  content:"真 是"

  -----------------------------------

  结果出来了也印证了上面想法但是明明有条记录同时包含这两个字了为什么没有搜索到呢?是不是加个空格就可以了呢?把“真”变成“真 再来试试

  搜索词:真 是

  结果:

  content:真 content:是

  测试测

  测试

  -----------------------------------

  真神奇表达式变掉了而且只包含个“是”但是没有“真”记录也出来了这表明什么?这表明现在语句就是或关系只要满足包含“是”或者包含“真”就可以搜索到了

  (以上内容前面章节有提到现在开始进入正式气氛——Birdshover)

  但是我现在就想要搜索同时包含两个字记录如何办呢?嘿嘿在每个字前面加个“+”号试试关键词变成“+真 +是”看看结果:

  搜索词:+真 +是

  结果:

  +content:真 +content:是

  测试测

  -----------------------------------

  那现在我要搜索包含“是”但是不包含“真”结果如何办?试试这个语句“-真 +是”

  搜索词:-真 +是

  结果:

  -content:真 +content:是

  测试

  -----------------------------------

  和或非终于被我们折腾完了

  整理总结下关系就是:

  a & b =>  +a +b

  a || b =>  a  b

  a !b  =>  +a -b

  4.3.3 如何用Query构造和或非

  Lucene.Net框架提供Query也是可以完成和或非运算般用BooleanQuery来构造如何构造?现在对搜索部分代码进行变动变成4.3.3.1

代码 4.3.3.1
    /// <summary>
    /// 执行测试入口
    /// </summary>
    [Test]
    public void SearcherTest
    {
      Index;
      List<> list = List<> { "真是" };
      for ( i = 0; i < list.Count; i)
      {
        Console.WriteLine("搜索词:" + list[i]);
        Console.WriteLine("结果:");
        Searcher(list[i]);
        Console.WriteLine("-----------------------------------");
      }
    }
    /// <summary>
    /// 搜索
    /// </summary>
    /// <param name="query">搜索输入</param>
    private void Searcher( query)
    {
      Analyzer analyzer = StandardAnalyzer;
      //构造BooleanQuery
      QueryParser parser = QueryParser("content", analyzer);
      BooleanQuery bquery = BooleanQuery;
      TokenStream ts = analyzer.TokenStream(null, StringReader(query));
      Lucene.Net.Analysis.Token token;
      while ((token = ts.Next) != null)
      {
        Query query = parser.Parse(token.TermText);
        bquery.Add(query, BooleanClause.Occur.MUST);
      }
      //构造完成
      IndexSearcher searcher = IndexSearcher("IndexDirectory");
      
      //Query query = parser.Parse(query);
      //输出我们要查看表达式
      Console.WriteLine(bquery.);
      Hits hits = searcher.Search(bquery);
      for ( i = 0; i < hits.Length; i)
      {
        Document doc = hits.Doc(i);
        Console.WriteLine(doc.Get("title"));
      }
    }




  测试:

  搜索词:真是

  结果:

  +content:真 +content:是

  测试测

  -----------------------------------

  构造出和表达式了把BooleanQueryAdd思路方法第 2个参数换成BooleanClause.Occur.SHOULD

  bquery.Add(query, BooleanClause.Occur.SHOULD);

  这个就是或:

  搜索词:真是

  结果:

  content:真 content:是

  测试测

  测试

  -----------------------------------

  而换成 bquery.Add(query, BooleanClause.Occur.MUST_NOT);这个就是非了:

  搜索词:真是

  结果:

  -content:真 -content:是

  -----------------------------------

  4.3.4 其它特使符号

  如果形容"+-"为Lucene.Net运算符那只有这么两个也太单调了实际上它还有其它运算符

  +-!:^{}~*?

  上面都是它运算符号这么多运算符用起来很方便但是也就出现另外个问题

  什么问题?下节再讲



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: