博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene基础(2)
阅读量:7224 次
发布时间:2019-06-29

本文共 9557 字,大约阅读时间需要 31 分钟。

上一篇:

一、Lucene术语

Document, Field, Term, Query, Analyzer相信在其中大多数在之前已经理解了...对其中部分概念详细说明

Document是一个包含了多个Field的容器,通过以下代码应该容易理解二者的关系

Document document=new Document();        //Field.Store.YES或者NO(存储域选项)        //设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原        //设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完全还原(doc.get)        for(int i=0;i

Field的一般构造器:

protected Field(String name, FieldType type)

下面说明常见的FieldType

(1) NumbericType

public enum NumericType {    /** 32-bit integer numeric type */    INT,     /** 64-bit long numeric type */    LONG,     /** 32-bit float numeric type */    FLOAT,     /** 64-bit double numeric type */    DOUBLE  }

如果是数值类型,可以通过NumbericType来指明

(2) Stored

private boolean stored;

是否存储field的值。如果true,原始的字符串值全部被保存在索引中,并可以由IndexReader类恢复。该选项对于需要展示搜索结果的一些域很有用(如URL,标题等)。如果为false,则索引中不存储field的值,通常用来索引大的文本域值。如Web页面的正文

(3) tokenized

private boolean tokenized = true;

是否使用分析器将域值分解成独立的语汇单元流。该属性仅当indexed()为true时有效.

(4) 加权相关

  • private boolean storeTermVectors;当lucene建立起倒排索引后,默认情况下它会保存所有必要的信息实施Vector Space Model。该Model需要计算文档中出现的term数,以及他们出现的位置。该属性仅当indexed为true时生效。他会为field建立一个小型的倒排索引。
  • private boolean storeTermVectorOffsets;表示是否存储field的token character的偏移量到 term vectors向量中。
  • private boolean storeTermVectorPositions;表示是否存储field中token的位置到term vectors 向量中。
  • private boolean storeTermVectorPayloads;是否存储field中token的比重到term vectors中。
  • private boolean omitNorms;是否要忽略field的加权基准值,如果为true可以节省内存消耗,但在打分质量方面会有更高的消耗,另外你也不能使用index-time 进行加权操作。

(5) IndexOptions

// NOTE: order is important here; FieldInfo uses this  // order to merge two conflicting IndexOptions (always  // "downgrades" by picking the lowest).  /** Not indexed */  NONE,  /**    * Only documents are indexed: term frequencies and positions are omitted.   * Phrase and other positional queries on the field will throw an exception, and scoring   * will behave as if any term in the document appears only once.   */  DOCS,  /**    * Only documents and term frequencies are indexed: positions are omitted.    * This enables normal scoring, except Phrase and other positional queries   * will throw an exception.   */    DOCS_AND_FREQS,  /**    * Indexes documents, frequencies and positions.   * This is a typical default for full-text search: full scoring is enabled   * and positional queries are supported.   */  DOCS_AND_FREQS_AND_POSITIONS,  /**    * Indexes documents, frequencies, positions and offsets.   * Character offsets are encoded alongside the positions.    */  DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS,

说明如下:

  • DOCS_ONLY:仅documents被索引,term的频率和位置都将被忽略。针对field的短语或有关位置的查询都将抛出异常。 
  • DOCS_AND_FREQS:documents和term的频率被索引,term的位置被忽略。这样可以正常打分,但针对field的短语或有关位置的查询都将抛出异常。 
  • DOCS_AND_FREQS_AND_POSITIONS:这是一个全文检索的默认设置,打分和位置检索都支持。 
  • DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS:索引字符相对位置的偏移量。

(6) DocValueType

/**   * No doc values for this field.   */  NONE,  /**    * A per-document Number   */  NUMERIC,  /**   * A per-document byte[].  Values may be larger than   * 32766 bytes, but different codecs may enforce their own limits.   */  BINARY,  /**    * A pre-sorted byte[]. Fields with this type only store distinct byte values    * and store an additional offset pointer per document to dereference the shared    * byte[]. The stored byte[] is presorted and allows access via document id,    * ordinal and by-value.  Values must be {
@code <= 32766} bytes. */ SORTED, /** * A pre-sorted Number[]. Fields with this type store numeric values in sorted * order according to {
@link Long#compare(long, long)}. */ SORTED_NUMERIC, /** * A pre-sorted Set<byte[]>. Fields with this type only store distinct byte values * and store additional offset pointers per document to dereference the shared * byte[]s. The stored byte[] is presorted and allows access via document id, * ordinal and by-value. Values must be {
@code <= 32766} bytes. */ SORTED_SET,

如果非空,field的值将被索引成docValues. 

  • NUMERIC:数字类型 
  • BINARY:二进制类型 
  • SORTED:只保存不同的二进制值 byte[] 
  • SORTED_SET.

(7) frozen

阻止field属性未来可能的变更,该属性通常在FieldType 属性已经被设置后调用。是为了防止无意识的变更

 

二、增删改查演示

原文链接:

 

public class IndexerCRUD {    //测试数据,模拟数据库表结构    private static String[] ids={"1","2","3"}; //用户ID    private static String [] names={"kl","wn","sb"};    private static String [] describes={"shi yi ge mei nan zi","Don't know","Is an idiot\n"};    //索引存储地址    private static String indexDir="G:\\projects-helloworld\\lucene\\src\\main\\resources\\LuceneIndex";    /**     * 获取操作索引实体,并添加测试数据     * @param indexDir 索引存储位置     * @return     * @throws Exception     */    public static IndexWriter getIndexWriter(String indexDir)throws Exception{        IndexWriterConfig writerConfig=new IndexWriterConfig(getAnalyzer());        IndexWriter indexWriter=new IndexWriter(getDirectory(indexDir),writerConfig);        Document document=new Document();        //Field.Store.YES或者NO(存储域选项)        //设置为YES表示或把这个域中的内容完全存储到文件中,方便进行文本的还原        //设置为NO表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完全还原(doc.get)        for(int i=0;i
"+doc.get("ids")); } reader.close(); } catch (Exception e) { e.printStackTrace(); } }

 

 

 

 三、常见Query用法

 

Query 是一个用于查询的抽象基类。搜索指定单词或词组涉及到在项中包装它们,将项添加到查询对象,将查询对象传递到 IndexSearcher 的搜索方法。

 

Lucene 包含各种类型的具体查询实现,比如 TermQuery、BooleanQuery、PhraseQuery、PrefixQuery、RangeQuery、MultiTermQuery、FilteredQuery、SpanQuery 等。以下部分讨论 Lucene 查询 API 的主查询类。

Basic: QueryParser和ScoreDoc

QueryParser 对于解析人工输入的查询字符非常有用。您可以使用它将用户输入的查询表达式解析为 Lucene 查询对象,这些对象可以传递到 IndexSearcher 的搜索方法。它可以解析丰富的查询表达式。 QueryParser 内部将人们输入的查询字符串转换为一个具体的查询子类。您需要使用反斜杠(\)将 *、? 等特殊字符进行转义。您可以使用运算符 AND、OR 和 NOT 构建文本布尔值查询。

QueryParser queryParser = new QueryParser("subject",new StandardAnalyzer());// Search for emails that contain the words 'job openings' and '.net' and 'pune'Query query = queryParser.parse("job openings AND .net AND pune");

indexSearcher 返回一组对分级搜索结果(如匹配给定查询的文档)的引用。您可以使用 IndexSearcher 的搜索方法确定需要检索的最优先搜索结果数量。可以在此基础上构建定制分页。您可以添加定制 Web 应用程序或桌面应用程序来显示搜索结果。检索搜索结果涉及的主要类包括 ScoreDoc 和 TopDocs。

ScoreDoc: 搜索结果中包含一个指向文档的简单指针。这可以封装文档索引中文档的位置以及 Lucene 计算的分数。 

封装搜索结果以及 ScoreDoc 的总数。 
以下代码片段展示了如何检索搜索结果中包含的文档。

/* First parameter is the query to be executed and second parameter indicates the no of search results to fetch */ TopDocs topDocs = indexSearcher.search(query,20); System.out.println(“Total hits “+topDocs.totalHits);// Get an array of references to matched documents ScoreDoc[] scoreDosArray = topDocs.scoreDocs; for(ScoreDoc scoredoc: scoreDosArray){ //Retrieve the matched document and show relevant details   Document doc = indexSearcher.doc(scoredoc.doc);   System.out.println(“\nSender: “+doc.getField(“sender”).stringValue());   System.out.println(“Subject: “+doc.getField(“subject”).stringValue());   System.out.println(“Email file location: ” +doc.getField(“emailDoc”).stringValue()); }

 

3.1 TermQuery

搜索索引最基本的查询类型。可以使用单个项构建TermQuery。项值应该区分大小写,但也并非全是如此。注意,传递的搜索项应该与文档分析得到的项一致,因为分析程序在构建索引之前对原文本执行许多操作。 

例如,考虑电子邮件标题 “Job openings for Java Professionals at Bangalore”。假设您使用 StandardAnalyzer 编制索引。现在如果我们使用 TermQuery 搜索 “Java”,它不会返回任何内容,因为本文本应该已经规范化,并通过 StandardAnalyzer 转成小写。如果搜索小写单词 “java”,它将返回所有标题字段中包含该单词的邮件。

 

//Search mails having the word "java" in the subject fieldSearcher indexSearcher = new IndexSearcher(indexDirectory);Term term = new Term("subject","java");Query termQuery = new TermQuery(term);TopDocs topDocs = indexSearcher.search(termQuery,10);

 

3.2 RangeQuery

您可以使用 RangeQuery 在某个范围内搜索。索引中的所有项都以字典顺序排列。Lucene 的 RangeQuery 允许用户在某个范围内搜索项。该范围可以使用起始项和最终项(包含两端或不包含两端均可)指定。

 

/* RangeQuery example:Search mails from 01/06/2009 to 6/06/2009both inclusive */Term begin = new Term("date","20090601");Term end = new Term("date","20090606");Query query = new RangeQuery(begin, end, true);

 

3.3 PrefixQuery

您可以使用 PrefixQuery 通过前缀单词进行搜索,该方法用于构建一个查询,该查询查找包含以指定单词前缀开始的词汇的文档。

//Search mails having sender field prefixed by the word 'job'PrefixQuery prefixQuery = new PrefixQuery(new Term("sender","job"));PrefixQuery query = new PrefixQuery(new Term("sender","job"));

 

3.4 BooleanQuery

您可以使用 BooleanQuery 组合任何数量的查询对象,构建强大的查询。它使用 query 和一个关联查询的子句,指示查询是应该发生、必须发生还是不得发生。在 BooleanQuery 中,子句的最大数量默认限制为 1,024。您可以调用 setMaxClauseCount 方法设置最大子句数。

// Search mails have both 'java' and 'bangalore' in the subject fieldQuery query1 = new TermQuery(new Term("subject","java"));Query query2 = new TermQuery(new Term("subject","bangalore"));BooleanQuery query = new BooleanQuery();query.add(query1,BooleanClause.Occur.MUST);query.add(query2,BooleanClause.Occur.MUST);

 

3.5 PhraseQuery

您可以使用 PhraseQuery 进行短语搜索。PhraseQuery 匹配包含特定单词序列的文档。PhraseQuery 使用索引中存储的项的位置信息。考虑匹配的项之间的距离称为 slop。默认情况下,slop 的值为零,这可以通过调用 setSlop 方法进行设置。PhraseQuery 还支持多个项短语。

/* PhraseQuery example: Search mails that have phrase 'job opening j2ee'   in the subject field.*/PhraseQuery query = new PhraseQuery();query.setSlop(1);query.add(new Term("subject","job"));query.add(new Term("subject","opening"));query.add(new Term("subject","j2ee"));

 

3.6 WildcardQuery

WildcardQuery 实现通配符搜索查询,这允许您搜索 arch*(可以查找包含 architect、architecture 等)之类的单词。使用两个标准通配符: 

* 表示零个以上 
? 表示一个以上 
如果使用以通配符查询开始的模式进行搜索,则可能会引起性能的降低,因为这需要查询索引中的所有项以查找匹配文档。

//Search for 'arch*' to find e-mail messages that have word 'architect' in the subjectfield./Query query = new WildcardQuery(new Term("subject","arch*"));

 

3.7 FuzzyQuery

您可以使用 FuzzyQuery 搜索类似项,该类匹配类似于指定单词的单词。类似度测量基于 Levenshtein(编辑距离)算法进行。在列表 9 中,FuzzyQuery 用于查找与拼错的单词 “admnistrtor” 最接近的项,尽管这个错误单词没有索引。

/* Search for emails that have word similar to 'admnistrtor' in thesubject field. Note we have misspelled admnistrtor here.*/Query query = new FuzzyQuery(new Term("subject", "admnistrtor"));

 

转载于:https://www.cnblogs.com/carl10086/p/6021424.html

你可能感兴趣的文章
兄弟连ThinkPHP视频教程介绍
查看>>
自定义实用异常类
查看>>
Tomcat性能调优方案
查看>>
FFmpeg的安装与使用
查看>>
Linux安装 nginx 和 ftp组件
查看>>
谈谈对于企业级系统架构的理解
查看>>
查看LAMP编译时使用的参数
查看>>
python获取mysql天数据,聚合存入mongodb(我的第一个用python写的程序)
查看>>
spring的IOC和AOP详细讲解
查看>>
常用shell命令整理
查看>>
java常用正则验证表达式收集
查看>>
Hadoop 2.2.0单机版安装
查看>>
#CCNA#路由和交换机
查看>>
Spark(MLlib)
查看>>
判断单链表的值是否是回文结构
查看>>
java8-interface allow static and default methods
查看>>
How To Choose The Best XML Parser for Your iPho...
查看>>
趣图:程序员发型的逻辑代数
查看>>
a++与++a的区别
查看>>
ThinkPHP 使用U方法自动生成URL超链接
查看>>