热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

lucene.net学习六——多Field多索引文件的查询

在实际的需求中,我们需要输入一个关键语句,希望能搜索到标题中含有此关键词或者内容中也还有此关键语句的文章,这就是一个多Field查询的问题当然多Field之间的关系可能为“与”也有可能为“或”。一

在实际的需求中,我们需要输入一个关键语句,希望能搜索到标题中含有此关键词或者内容中也还有此关键语句的文章,这就是一个多Field查询的问题

当然多Field之间的关系可能为“与”也有可能为“或”。一般情况下,都在同一个目录索引下搜索,但是如果索引被分成很多文件,存在不同的地方,因此又会有一个多索引文件搜索的问题。下面通过代码演示:

首先编写建索引的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using Lucene.Net;
using Lucene.Net.Util;
using Lucene.Net.Store;
using Lucene.Net.Analysis;
using Lucene.Net.Index;
using Lucene.Net.Documents;

namespace TestIndexWriter
{
class Program
{
static void Main(string[] args)
{
//需要被索引的目录
FileInfo fi = new FileInfo(@"F:\doc");
//索引存放的路径
Lucene.Net.Store.Directory indexdir = FSDirectory.Open(new DirectoryInfo(@"F:\luceneindex1"));
//建立一个处理文本的分析器
Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
//创建索引写入器
IndexWriter writer = new IndexWriter(indexdir, analyzer, true, new IndexWriter.MaxFieldLength(10000));
//递归遍历指定目录下的所有的文件,并建立索引
IndexDocs(writer, fi);
Console.WriteLine("索引存放的目录为:F:\\luceneindex1");
writer.Close();
}

//遍历指定目录下的所有文件进行索引
private static void IndexDocs(IndexWriter writer, FileInfo file)
{
//判断指定的目录是否存在,注意不是文件的路径,C#中目录与文件的区别
//Directory.Exists()是判断指定的目录是否存在,而File.Exists()则是判断指定的文件是否存在
if (System.IO.Directory.Exists(file.FullName))
{
//获取指定目录中的所有文件和子目录
System.String[] files = System.IO.Directory.GetFileSystemEntries(file.FullName);
if (files != null)
{
for (int i = 0; i {
IndexDocs(writer, new System.IO.FileInfo(files[i]));//递归调用
}
}
}
//不是目录了,是文件,就开始加入索引
else
{
System.Console.WriteLine("开始索引文件: " + file.FullName);
try
{
Document d = new Document();
//对路径进行存储、索引但不分词
d.Add(new Field("path",file.FullName, Field.Store.YES, Field.Index.NOT_ANALYZED));
d.Add(new Field("contents", new StreamReader(file.FullName, System.Text.Encoding.Default)));
writer.AddDocument(d);
}
catch (System.IO.FileNotFoundException fnfe)
{
Console.WriteLine(fnfe.Message);
}
}
}
}
}

上面代码的意思是遍历目录F:\doc下的所有文件,并建立索引,建好后的索引存放在F:\luceneindex1下面。运行结果如下:

修改上面代码中的//需要被索引的目录
            FileInfo fi = new FileInfo(@"F:\doc1");
            //索引存放的路径
            Lucene.Net.Store.Directory indexdir = FSDirectory.Open(new DirectoryInfo(@"F:\luceneindex2"));

表示遍历目录F:\doc1下的所有文件,并建立索引,索引存放在F:\luceneindex2下,运行结果如下:

 

到此相当于生成了两个不同路径下的索引文件。

下面开始编写所Field多索引文件搜索的代码。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using Lucene.Net;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.QueryParsers;

namespace MultiFieldMultiSearch
{
class Program
{
static void Main(string[] args)
{
//索引存放的路径1
Lucene.Net.Store.Directory indexdir1 = FSDirectory.Open(new DirectoryInfo(@"F:\luceneindex1"));
//初始化一个读索引器1
IndexSearcher IS1 = new IndexSearcher(indexdir1, true);

//索引存放的路径2
Lucene.Net.Store.Directory indexdir2 = FSDirectory.Open(new DirectoryInfo(@"F:\luceneindex2"));
//初始化一个读索引器2
IndexSearcher IS2 = new IndexSearcher(indexdir2, true);
//查询器数组
IndexSearcher[] searchers={IS1,IS2};
//构造一个多索引的查询器
MultiSearcher search = new MultiSearcher(searchers);

//2个需要查询的域名称
string[] fields={"filename","contents"};
//将每个域Field所查询的结果设为“或”的关系,也就是取并集
BooleanClause.Occur[] clauses={BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};
//构造一个多Field查询
Query query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, "郭靖", fields, clauses,
new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
Console.WriteLine(string.Format("查询条件为:{0}", query.ToString()));
Hits hits = search.Search(query);
for (int i = 0; i {
//更具文档的编号得到文档对象
Document doc = hits.Doc(i);
//根据给定的Filed名,得到对应的值
Console.WriteLine(doc.Get("path"));
//输出此文档的得分在结果集中
Console.WriteLine(hits.Score(i));
}
search.Close();
}
}
}

运行输出结果为:

 在代码里面输入"郭靖"作为查询词,根据lucene.net的标准分词方法,将“郭靖”分解为“郭”、“靖”这两个词,建索引的时候也是这样分解的,所以一定要保证建索引用的分词器与查询时用的分词器保持一致。

上面的查询条件的意思就是搜索包含郭或靖的文件名的文件,搜索包含郭或靖的内容的文件,两者的结果取并集

结果中还返回了每一个文件Document的打分

 


推荐阅读
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • 在Java基础中,私有静态内部类是一种常见的设计模式,主要用于防止外部类的直接调用或实例化。这种内部类仅服务于其所属的外部类,确保了代码的封装性和安全性。通过分析JDK源码,我们可以发现许多常用类中都包含了私有静态内部类,这些内部类虽然功能强大,但其复杂性往往让人感到困惑。本文将深入探讨私有静态内部类的作用、实现方式及其在实际开发中的应用,帮助读者更好地理解和使用这一重要的编程技巧。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 本文详细介绍了在 Android 7.1 系统中调整屏幕分辨率和默认音量设置的方法。针对系统默认音量过大的问题,提供了具体的步骤来降低系统、铃声、媒体和闹钟的默认音量,以提升用户体验。此外,还涵盖了如何通过系统设置或使用第三方工具来优化屏幕分辨率,确保设备显示效果更加清晰和流畅。 ... [详细]
author-avatar
qiuqiu
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有