精华内容
下载资源
问答
  • 1选择高亮的颜色 2 选择替换,更多 3 选择格式,突出显示 注意替换为后面有突出显示才能正确突出显示,全部替换就行

     

     

    1选择高亮的颜色

    2  选择替换,更多

    3

    选择格式,突出显示

    注意替换为后面有突出显示才能正确突出显示,全部替换就行

     

     

    展开全文
  • Highlighters 高亮显示 日常生活中我们使用搜索工具尝试查询一些信息的时候,常常可以看到返回的结果集中和我们查询条件相符合的字段被特殊的颜色所标记,这就是结果高亮显示。通过高亮显示用户可以明显的发现查询...

    Highlighters 高亮显示

    日常生活中我们使用搜索工具尝试查询一些信息的时候,常常可以看到返回的结果集中和我们查询条件相符合的字段被特殊的颜色所标记,这就是结果高亮显示。通过高亮显示用户可以明显的发现查询匹配的位置,

    ES使用highlight来实现搜索结果中一个或多个字段突出显示。

    高亮显示需要字段中的内容,如果没有存储字段store=true,则加载实际的_source并从_source提取相关字段。

    简单的例子

    下面是一个简单的例子,使用的映射结构

    PUT article/_mapping
    {
        "properties": {
            "article_type": {
                "type": "keyword"
            },
            "article_title": {
                "type": "text"
            },
            "content": {
                "type": "text"
            },
            "date": {
                "type": "date",
                "format": ["yyyy-MM-dd HH:mm:ss"]
            },
            "read_num": {
                "type": "integer"
            },
            "comment_num": {
                "type": "integer"
            }
        }
    }
    

    数据内容就是本人的博客信息

    {"index":{"_index":"article","_id":0}}
    {"article_type": "原创","article_title": "Elasticsearch查询——Profile API(性能分析)","content": "Profile API 性能分析 平时开发的过程中我们可能需要对一些查询操作进行优化,而优化之前的工作就是要对操作的性能进行分析,而ES提供了Profile API来帮助用户进行性能分析。它让用户了解如何在较低的级别执行搜索请求,这样用户就可以理解为什么某些请求比较慢,并采取措施改进它们。","date": "2019-12-22 22:22:29","read_num": 4,"comment_num": 0}
    {"index":{"_index":"article","_id":1}}
    {"article_type": "原创","article_title": "Elasticsearch查询——Search Template(模板查询)","content": "关于版本 内容 版本 Elasticsearch版本 7.2.0 ES模板搜索——Search Template 日常开发中我们可能需要频繁的使用一些类似的查询。为了减少重复的工作,我们可以将这些类似的查询写成模板,在后续只需要传递不同的参数来调用模板获取结果。 模板的保存和删","date": "2019-12-19 23:48:14","read_num": 2,"comment_num": 0}
    {"index":{"_index":"article","_id":2}}
    {"article_type": "原创","article_title": "Elasticsearch查询——URI Search(简单查询字符串)","content": "简单查询字符串——URI Search 实际业务中我们通常都是使用一个完整的请求体从elasticsearch获得数据。然而在有些时候我们为了调试系统或者数据的时候需要临时进行一些简单的查询时候,编写完整的请求体JSON可能会稍微麻烦。而elasticsearch提供了一种基于URI的简单的查询方","date": "2019-12-18 21:58:18","read_num": 10,"comment_num": 0}
    {"index":{"_index":"article","_id":3}}
    {"article_type": "原创","article_title": "Elasticsearch摄取节点(十)——GeoIP以及Grok处理器","content": "IP解析处理器(GeoIP Processor) 处理器作用 GeoIP Processor主要是根据IP地址解析出具体的地理位置信息的处理器。此处理器需要配合Maxmind数据库中的数据。 ingest-geoip模块附带的GeoLite2 City、GeoLite2 Country和GeoLi","date": "2019-12-18 20:52:10","read_num": 4,"comment_num": 0}
    {"index":{"_index":"article","_id":4}}
    {"article_type": "原创","article_title": "Elasticsearch脚本使用","content": "如何使用Elasticsearch脚本 Elasticsearch默认脚本语言为Painless。其他lang插件使您可以运行以其他语言编写的脚本。 语言 沙盒 是否需要插件 备注 painless 是 内置的 默认脚本语言 expression 是 内置的 快速的自定义排名和","date": "2019-12-14 15:10:07","read_num": 11,"comment_num": 0}
    ......
    

    执行下面请求之后在返回内容中除了常规的数据匹配之外还存在highlight对象,此对象中会将查询字段中和查询条件一直的内容使用预设的HTML标签进行包裹。

    GET article/_search
    {
        "size":5,
        "query": {
            "match": {
                "content": "简单的查询"
            }
        },
        "highlight": {
            "boundary_scanner_locale":"zh_CN",
            "fields": {
                "content": {
                    "pre_tags": [
                        "<em>"
                    ],
                    "post_tags": [
                        "</em>"
                    ]
                }
            }
        }
    }
    
    ## 返回内容
    
    "highlight" : {
      "content" : [
    	"<em>简</em><em>单</em><em>查</em><em>询</em>字符串——URI Search 实际业务中我们通常都是使用一个完整<em>的</em>请求体从elasticsearch获得数据。",
    	"然而在有些时候我们为了调试系统或者数据<em>的</em>时候需要临时进行一些<em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>时候,编写完整<em>的</em>请求体JSON可能会稍微麻烦。而elasticsearch提供了一种基于URI<em>的</em><em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>方"
      ]
    }
    

    高亮设置

    下面的参数可以设置在highlight的下一级此时未全局设置,也可以设置在字段的下一级,此时为字段设置。单个字段的设置优先级高于全局设置。比如下面的请求中最终匹配的短语会被

    包裹.

    GET article/_search
    {
        "size":5,
        "query": {
            "match": {
                "content": "简单的查询"
            }
        },
        "highlight": {
            "boundary_scanner_locale":"zh_CN",
            "boundary_scanner":"sentence",
            "fragmenter":"span", 
            "pre_tags": ["<em>"],
            "post_tags": ["</em>"],
            "fields": {
                "content": {
                   "pre_tags": [
                        "<h1>"
                    ],
                    "post_tags": [
                        "</h1>"
                    ] 
                }
            }
        }
    }
    

    高亮参数

    参数 说明
    boundary_chars 包含每个边界字符的字符串。默认为,! ?\ \ n。
    boundary_max_scan 扫描边界字符的距离。默认为20。
    boundary_scanner 指定如何分割突出显示的片段,支持chars, sentence, or word三种方式。
    boundary_scanner_locale 用来设置搜索和确定单词边界的本地化设置,此参数使用语言标记的形式(“en-US”, “fr-FR”, “ja-JP”)
    encoder 表示代码段应该是HTML编码的:默认(无编码)还是HTML (HTML-转义代码段文本,然后插入高亮标记)
    fields 指定检索高亮显示的字段。可以使用通配符来指定字段。例如,可以指定comment_*来获取以comment_开头的所有文本和关键字字段的高亮显示。
    force_source 根据源高亮显示。默认值为false。
    fragmenter 指定文本应如何在突出显示片段中拆分:支持参数simple或者span。
    fragment_offset 控制要开始突出显示的空白。仅在使用fvh highlighter时有效。
    fragment_size 字符中突出显示的片段的大小。默认为100。
    highlight_query 突出显示搜索查询之外的其他查询的匹配项。这在使用重打分查询时特别有用,因为默认情况下高亮显示不会考虑这些问题。
    matched_fields 组合多个匹配结果以突出显示单个字段,对于使用不同方式分析同一字符串的多字段。所有的matched_fields必须将term_vector设置为with_positions_offsets,但是只有将匹配项组合到的字段才会被加载,因此只有将store设置为yes才能使该字段受益。只适用于fvh highlighter。
    no_match_size 如果没有要突出显示的匹配片段,则希望从字段开头返回的文本量。默认为0(不返回任何内容)。
    number_of_fragments 返回的片段的最大数量。如果片段的数量设置为0,则不会返回任何片段。相反,突出显示并返回整个字段内容。当需要突出显示短文本(如标题或地址),但不需要分段时,使用此配置非常方便。如果number_of_fragments为0,则忽略fragment_size。默认为5。
    order 设置为score时,按分数对突出显示的片段进行排序。默认情况下,片段将按照它们在字段中出现的顺序输出(order:none)。将此选项设置为score将首先输出最相关的片段。每个高亮应用自己的逻辑来计算相关性得分。
    phrase_limit 控制文档中所考虑的匹配短语的数量。防止fvh highlighter分析太多的短语和消耗太多的内存。提高限制会增加查询时间并消耗更多内存。默认为256。
    pre_tags 与post_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
    post_tags 与pre_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
    require_field_match 默认情况下,只突出显示包含查询匹配的字段。将require_field_match设置为false以突出显示所有字段。默认值为true。
    tags_schema 设置为使用内置标记模式的样式。
    type 使用的高亮模式:unified, plain, or fvh. 默认为 unified。

    高亮参数内容的补充

    boundary_scanner

    指定如何分割突出显示的片段,支持chars, sentence, or word三种方式。默认unified highlighter使用
    sentence,fvh highlighter使用chars。

    • chars

    使用boundary_chars指定的字符突出显示边界。boundary_max_scan设置控制扫描边界字符的距离。只适用于fvh highlighter。

    • sentence

    根据Java的BreakIterator确定,在下一个句子边界处中断突出显示的片段。配置了此参数后上面例子返回内容,可以看到其每个分段都是一个句子

    "highlight" : {
      "content" : [
    	"<em>简</em><em>单</em><em>查</em><em>询</em>字符串——URI Search 实际业务中我们通常都是使用一个完整<em>的</em>请求体从elasticsearch获得数据。",
    	"然而在有些时候我们为了调试系统或者数据<em>的</em>时候需要临时进行一些<em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>时候,编写完整<em>的</em>请求体JSON可能会稍微麻烦。而elasticsearch提供了一种基于URI<em>的</em><em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>方"
      ]
    }
    
    • word

    根据Java的BreakIterator确定,在下一个单词边界处中断突出显示的片段。使用此参数上面的例子返回内容,此时每个分段并不是一个完整的句子。

    "highlight" : {
      "content" : [
    	"<em>简</em><em>单</em><em>查</em><em>询</em>字符串",
    	"实际业务中我们通常都是使用一个完整<em>的</em>请求体从",
    	"然而在有些时候我们为了调试系统或者数据<em>的</em>时候需要临时进行一些<em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>时候",
    	"编写完整<em>的</em>请求体",
    	"<em>的</em><em>简</em><em>单</em><em>的</em><em>查</em><em>询</em>方"
      ]
    }
    

    boundary_scanner_locale

    用来设置搜索和确定单词边界的本地化设置

    1. 可以通过https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#forLanguageTag-java.lang.String-获得更多语言标签

    2. 默认参数为[Locale.ROOT]{https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#ROOT}

    fragmenter

    指定文本应如何在突出显示片段中拆分。只适用于plain highlighter。默认为span。

    1. simple:将文本分割成相同大小的片段
    2. span:将文本分割为大小相同的片段,但尽量避免在突出显示的术语之间分割文本。这在查询短语时很有用

    type

    type字段允许强制使用特定的高亮策略。可以配置的参数:unified, plain and fvh。下面是一个使用plain策略的例子:

    GET article/_search
    {
        "query" : {
            "match": { "content": "简单的查询" }
        },
        "highlight" : {
            "fields" : {
                "content" : {"type" : "plain"}
            }
        }
    }
    

    三种不同的高亮策略的区别

    1. unified(通用高亮策略)

    其使用的是Lucene的Unified Highlighter。此高亮策略将文本分解成句子,并使用BM25算法对单个句子进行评分,支持精确的短语和多术语(模糊、前缀、正则表达式)突出显示。这个是默认的高亮策略。

    1. plain (普通高亮策略)

    其使用的是Lucene的standard Lucene highlighter。它试图在理解词的重要性和短语查询中的任何词定位标准方面反映查询匹配逻辑。此高亮策略是和在单个字段中突出显示简单的查询匹配。如果想用复杂的查询在很多文档中突出显示很多字段,还是使用unified

    1. Fast vector highlighter(快速向量策略)

    其使用的是Lucene的Fast Vector highlighter。使用此策略需要在映射中将对应字段中属性term_vector设置为with_positions_offsets。这个策略以后会单独介绍。

    pre_tags和post_tags

    默认情况下,高亮显示将以和包装突出显示的文本。这可以通过设置pre_tags和post_tags来控制,例如:

    GET article/_search
    {
        "size":5,
        "query": {
            "match": {
                "content": "简单的查询"
            }
        },
        "highlight": {
            "boundary_scanner_locale":"zh_CN",
            "fields": {
                "content": {
                   "pre_tags": [
                        "<h1>"
                    ],
                    "post_tags": [
                        "</h2>"
                    ] 
                }
            }
        }
    }
    

    当然也可以使用系统预设的标签模式:

    GET article/_search
    {
        "size":5,
        "query": {
            "match": {
                "content": "简单的查询"
            }
        },
        "highlight": {
            "boundary_scanner_locale":"zh_CN",
            "tags_schema" : "styled",
            "fields": {
                "content": {
                    
                }
            }
        }
    }
    

    fragment_size 和 number_of_fragments

    fragment_size主要控制了每个高亮片段的大小,而number_of_fragments控制了返回多少个高亮片段。下面例子中就是控制返回两个长度10的片段

    GET article/_search
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "content": "简单的查询"
                        }
                    }
                ]
            }
        },
        "highlight": {
            "boundary_scanner_locale": "zh_CN",
            "fields": {
                "content": {
                  "fragment_size" : 10,
                  "number_of_fragments" : 2
                }
            }
        }
    }
    

    order

    order控制了返回对象中highlight片段的排序。下面例子中返回的高亮片段将会根据分数顺序输出。假如设置了none则是按照顺序输出。

    GET article/_search
    {
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "content": "简单的查询"
                        }
                    }
                ]
            }
        },
        "highlight": {
            "order" : "score",
            "boundary_scanner_locale": "zh_CN",
            "fields": {
                "content": {}
            }
        }
    }
    

    对一个字段进行查询的时候希望高亮其他字段

    在请求参数highlight中可以设置多个字段,同时需要为每个字段配置highlight_query。通过配置这个字段可以实现对content进行匹配查询同时高亮article_titlecontent字段的内容。同时使用此方法可以实现使用使用查询条件查询,而最终高亮字符串内容。

    GET article/_search
    {
        "query": {
            "match": {
                "content": "查询"
            }
        },
        "highlight": {
            "fields": {
                "content": {
                    "type": "unified",
                    "highlight_query": {
                        "bool": {
                            "must": {
                                "match": {
                                    "content": {
                                        "query": "字符串"
                                    }
                                }
                            },
                            "minimum_should_match": 0
                        }
                    }
                },
                "article_title": {
                    "type": "unified",
                    "highlight_query": {
                        "bool": {
                            "must": {
                                "match": {
                                    "article_title": {
                                        "query": "字符串"
                                    }
                                }
                            },
                            "minimum_should_match": 0
                        }
                    }
                }
            }
        }
    }
    

    highlighter如何确定高亮内容

    为了从查询的词汇中获得搜索片段位置,高亮策略显示需要知道原始文本中每个单词的起始和结束字符偏移量。目前根据模式不同获取这些数据途径不同

    1. 检索列表,如果在映射中index_options设置了offsets,unified会将其中数据应用在文档中,而不会重新分析文本。它直接对文档进行原始查询,并从索引中提取匹配的偏移数据。在字段内容很大的时候,使用此配置很重要,因为它不需要重新分析文本内容。和term_vectors相比,它还需要更少的磁盘空间。
    2. 术语向量,如果在映射中term_vector设置为with_positions_offsets则unified highlighter使用term_vector来突出显示字段。对于大字段(大于1MB)和多术语查询它的速度会比较快。而fvh highlighter总是使用term_vector
    3. 普通的高亮策略(
      Plain highlighting),当没有其他选择的时候,unified highlighter使用此模式,他在内存中创建一个小的索引(index),通过运行Lucene的查询执行计划来访问文档的匹配信息,对需要高亮显示的每个字段和每个文档进行处理。plain highlighter总是使用此策略。注意此方式在大型文本上可能需要大量的时间和内存。在使用此策略时候可以设置分析的文本字符的最大数量限制为1000000。这个数值可以通过修改索引的index.highlight.max_analyzed_offset参数来改变。

    个人水平有限,上面的内容可能存在没有描述清楚或者错误的地方,假如开发同学发现了,请及时告知,我会第一时间修改相关内容。假如我的这篇内容对你有任何帮助的话,麻烦给我点一个赞。你的点赞就是我前进的动力。

    展开全文
  • 中文的 点击视图,选中文字加亮即可 英文的 点击view,选中Word Highlighting

    中文的
    点击视图,选中文字加亮即可
    英文的
    点击view,选中Word Highlighting

    展开全文
  • Lucene笔记+PaodingAnalyzer+高亮显示 [转] 作者:王美凤 类别:生活理财 查看次数:1482 [1] (1) Lucene是一个基于Java全文搜索引擎,利用它可以轻易地为Java软件加入全文搜寻功能。 (2) Lucene能做什么...
    Lucene笔记+PaodingAnalyzer+高亮显示 [转] 
    作者:王美凤 类别:生活理财 查看次数:1482

    [1]
    (1)
    Lucene是一个基于Java全文搜索引擎,利用它可以轻易地为Java软件加入全文搜寻功能。
    (2)
    Lucene能做什么?
    Lucene可以对任何的数据做索引和搜索。 Lucene不管数据源是什么格式,只要它能被转化为文字的形式,就可以被Lucene所分析利用。也就是说不管是MS word, Html ,pdf还是其他什么形式的文件只要你可以从中抽取出文字形式的内容就可以被Lucene所用。
    (3)
    Lucene实现全文检索功能主要有三个步骤
    1、 建立索引
    建立索引是全文搜索的基础,lucene根据索引搜索用户需要查找的目标文档,如果没有索引也就无所谓搜索。
    2、 查找索引
    当索引建立好后,就可以对其进行查找了。Lucene所建立的索引是存放在文件系统中的.
    3、 更新索引
    由于我们要查找的内容总是不断变化的,所以索引文件也不是一成不变的,而是一个不断更新的过程。Lucene也提供了丰富的功能来支持索引的更新功能。
    [2]
    Lucene几个重要概念:
    (1)
    Document:一个要进行索引的单元,相当于数据库的一行纪录,任何想要被索引的数据,都必须转化为
    Document对象存放。
    (2)
    Field:Document中的一个字段,相当于数据库中的Column。
    IndexWriter:负责将Document写入索引文件。通常情况下,IndexWriter的构造函数包括了以下3个参数
    :索引存放的路径,分析器和是否重新创建索引。特别注意的一点,当IndexWriter执行完addDocument方法后,一定要记得调用自身的close方法来关闭它。只有在调用了close方法后,索引器才会将存放在内在中的所有内容写入磁盘并关闭输出流。
    Analyzer:分析器,主要用于文本分词。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,
    WhitespaceAnalyzer分析器等。
    Field对象
    从Lucene的源代码中,可以看出Field 典型构造函数如下:
    Field(String name, String value, Field.Store store, Field.Index index)
    其中:
    Field.Index有四种属性,分别是:
    Field.Index.TOKENIZED:分词索引
    Field.Index.UN_TOKENIZED:不分词进行索引,如作者名,日期等,不再需要分。
    Field.Index.NO:不进行索引,存放不能被搜索的内容如文档的一些附加属性如文档类型, URL等。
    Field.Index.NO_NORMS:不分词,建索引.但是Field的值不像通常那样被保存,而是只取一个byte,这样节约存储空间。
    Field.Store也有三个属性,分别是:
    Field.Store.YES:索引文件本来只存储索引数据, 此设计将原文内容直接也存储在索引文件中,如文档的标题。
    Field.Store.NO:原文不存储在索引文件中,搜索结果命中后,再根据其他附加属性如文件的Path,数据库的主键等,重新连接打开原文,适合原文内容较大的情况。
    Field.Store.COMPRESS 压缩存储。
    (3)
    Directory:索引存放的位置。Lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地Lucene提供了FSDirectory和RAMDirectory两个类。
    (4)
    Segment:段,是Lucene索引文件的最基本的一个单位。Lucene说到底就是不断加入新的Segment,然后按一定的规则算法合并不同的Segment以合成新的Segment。
    [3]
    用lucene作搜索,主要步骤:
    (1)建立索引:
    1.创建IndexWriter.
    2.创建Document,将各个document放入writer中.
    3.对于数据库查询,先将要查询的内容,从数据库中获取出来.用rs进行循环放入到doc中.
    同时应用增量索引:用一个文本记录当前已做索引的最后一个ID,下次做索引,从此文件获取ID,从它的
    下一个ID进行做索引追加到原来的索引文件中.而不是重头做索引.
    (2)进行搜索:
    1.new IndexSearcher(索引目录)=searcher
    2.添加各种查询器,生成query.
    3.searcher.search(query);
    4.返回Hits,用hits.length(),hits.doc(i)来输出doc,再用doc.get("field名")输出.
    (3)
    进行多域搜索:
    0.new IndexSearcher(索引目录)创建多个要查询的索引文件,再放于数组中,最近放于MultiSearcher
    1.建立field[],occurs[]
    2.建立多域查询器:MultiFieldQueryParser
    3.searcher.search(query);返回Hits
    4.用Hits.doc(n);可以遍历出Document
    (4)
    搜索数据库:
    1.可轻在根目录下建立一个index的目录,用来存放index.
    2.对数据表某表进行查询,将查询出来的字段结果-->放于document中-->通过indexwriter放入index目录中.
    3.查询时,同上.
    4.在JSP页面,导入lucene类.可以设置一个field,填写查询条件,提交到hits=searcher.search()中,将
    hits结果,放于中显示出来.
    (5)
    增量查询,方法基础同上.只是在创建index时,不同:
    1.增加多一个文本文件,来存放建立索引的数据表最后的ID,对数据表进行查询时,在SQL中添加 where id > **,则是采用增量索引.而不是重头再来.

    [4]
    实例
    (1)数据库索引实例:
    索引辅助类:
    public class JLuceneUtils {

    public static Document createConfigDoc(String id,String confContext)
    {
    Document doc=new Document();
    doc.add(new Field("id",id,Field.Store.YES,Field.Index.TOKENIZED));
    doc.add(new Field("confContext",confContext,Field.Store.YES,Field.Index.TOKENIZED));
    return doc;
    }

    public static String getStoreId(String idPath)
    {
    String storeId=null;
    try {
    File file = new File(idPath);
    if (!file.exists())
    file.createNewFile();
    FileReader reader=new FileReader(file);
    BufferedReader br=new BufferedReader(reader);
    storeId=br.readLine();
    if(storeId==null||storeId=="")
    storeId="0";
    br.close();
    reader.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return storeId;
    }

    public static boolean writeStoreId(String idPath,String id )
    {
    boolean b = false;
    try {
    File file = new File(idPath);
    if (!file.exists()) {
    file.createNewFile();
    }
    FileWriter fw = new FileWriter(idPath);
    PrintWriter out = new PrintWriter(fw);
    out.write(id);
    out.close();
    fw.close();
    b=true;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return b;
    }

    public static Hits luceneSearch(String indexPath,String searchMess)
    {
    Hits rs=null;
    try {
    IndexSearcher searcher = new IndexSearcher(indexPath);
    QueryParser parser = new QueryParser("id",new StandardAnalyzer());
    Query query=parser.parse(searchMess);
    rs=searcher.search(query);
    } catch (Exception e) {
    e.printStackTrace();
    }
    return rs;
    }
    }
    索引方法:
    public String luceneSearch()
    {
    String idPath="D:/tomcat_bbs/webapps/BBSCS_8_0_3/storeId.txt";
    String indexPath="D:/tomcat_bbs/webapps/BBSCS_8_0_3/index";
    try {
    File file = new File(indexPath);
    if (!file.exists()) {
    //for iBatis
    List bbsConfigs = (List) sqlMapClientTemplate.queryForList("getAllBBSConfig");
    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), true);
    for (int a = 0; a < bbsConfigs.size(); a++) {
    BBSConfig bbsConfig = (BBSConfig) bbsConfigs.get(a);
    Document doc = JLuceneUtils.createConfigDoc(bbsConfig.getId(), bbsConfig.getConfContext());
    writer.addDocument(doc);
    }
    writer.optimize(); //优化索引文件
    writer.close();
    }
    Hits hits = JLuceneUtils.luceneSearch(indexPath, searchMess);
    System.out.println("----------hits.length():" + hits.length());
    for (int a = 0; a < hits.length(); a++) {
    Document doc2 = (Document) hits.doc(a);
    System.out.println(searchMess + "的值是:"+ doc2.get("confContext"));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    // return "search";
    return SUCCESS;
    }

    (2)增量索引,各种高级索引
    增量查询:
    若用增量查询,则创建索引的逻辑,应该在用户点击索引时,先对storeID.txt中的ID与相应数据表中的ID进行对比,若有新记录则进行'创建索引',若无,则直接进行对现在索引文件的查询.
    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), false);
    对于增量索引,创建索引与搜索不能放在一起.因为增量索引,是追加,若放在一起,则每次进行搜索前,都会追回索引文件中已有的索引,造成重复.

    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), true);
    对于要索引的对象,若不是很大的话,不要用增量索引.因为增量索引涉及到更新索引问题.若用创建新索引,即索引文件会是最新的.

    对应数据表(jason_lucene):
    id name info date
    1 jason 中国人 20090610
    2 hwj 中原人 20090612
    3 hello 国人的事怀20090616
    4 jaosn 大家好 20090619

    辅助类,同上.
    实现方法:
    public String luceneSearch2()
    {
    try {
    String idPath = "D:/tomcat_bbs/webapps/BBSCS_8_0_3/index/storeId.txt";
    String indexPath = "D:/tomcat_bbs/webapps/BBSCS_8_0_3/index";
    //createIdnex 考虑增量功能
    String storeId = JLuceneUtils.getStoreId(idPath);
    String sql = "select id, name,info,date from jason_lucene where id >"+ storeId+" order by id";
    ResultSet rs2 = this.getResult(sql);
    String id="0";

    /*
    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), false);
    对于增量索引,创建索引与搜索不能放在一起.因为增量索引,是追加,若放在一起,则每次进行搜索前,都
    会追回索引文件中已有的索引,造成重复.

    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), true);
    对于要索引的对象,若不是很大的话,不要用增量索引.因为增量索引涉及到更新索引问题.若用创建新索
    引,即索引文件会是最新的.
    */

    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), false); //区别就在此!
    while(rs2.next())
    {
    Document doc=new Document();
    doc.add(new Field("name",rs2.getString("name"),Field.Store.YES,Field.Index.TOKENIZED));
    doc.add(new Field("info",rs2.getString("info"),Field.Store.YES,Field.Index.TOKENIZED));
    doc.add(new Field("date",rs2.getString("date"),Field.Store.YES,Field.Index.TOKENIZED));
    writer.addDocument(doc);
    id=rs2.getString("id");
    }
    writer.optimize();
    writer.close();
    boolean isSuccess=JLuceneUtils.writeStoreId(idPath, id);
    System.out.println("最新索引ID写入storeId.txt文件成功:"+isSuccess);

    //删除索引:
    IndexReader reader=IndexReader.open(indexPath);
    Term delterm=new Term("name","hwj"); //好像不支持中文.
    reader.deleteDocuments(delterm);
    reader.close();
    //更新索引:即是先用上面的方法删除特定的索引,然后再对特定的索引进行添加.添加方法也同上.

    //查询:
    IndexSearcher searcher = new IndexSearcher(indexPath);
    //1.普通查询:列出包含查询关键字的记录.可在关键字的前面添加+/-.如:
    //+jason -hwj:表示一定要包含jason,一定不要包含hwj
    // QueryParser parser = new QueryParser("info",new StandardAnalyzer());
    // Query query=parser.parse(searchMess);
    //2进行通配符查询:用*,表示0个或多个;?,表示一个. jas*,可查询出jaosn,jason.
    Query query1=new WildcardQuery(new Term("name",searchMess));
    //3模糊查询:若查询的关键字是jason ,则会查出jason,jaosn等相似的记录
    // Query query=new FuzzyQuery(new Term("name",searchMess));
    //4 范围查询:查询出在一个范围内的记录
    Term term1=new Term("date","20090611");
    Term term2=new Term("date","20090618");
    Query query2=new RangeQuery(term1,term2,true);
    //5多条件查询:
    BooleanQuery query=new BooleanQuery();
    query.add(query1, BooleanClause.Occur.MUST_NOT);
    query.add(query2, BooleanClause.Occur.MUST);
    Hits hits=searcher.search(query);
    System.out.println("符合查询条件'"+searchMess+"'的共有:" + hits.length() + "个结果");
    for (int a = 0; a < hits.length(); a++) {
    Document doc2 = (Document) hits.doc(a);
    System.out.println(doc2.get("name") + "的值是:"+ doc2.get("info"));
    }

    } catch (Exception e) {
    e.printStackTrace();
    }
    return SUCCESS;
    }

    (3)多域索引
    public class LuceneTest {

    public static void main(String[] args) {
    try {
    LuceneTest luceneTest = new LuceneTest();
    // 创建索引
    luceneTest.index();
    // 在索引所在目录下搜索"中国 金牌"
    luceneTest.search("中国 金牌");
    luceneTest.search("2008 jaosn");
    } catch (Exception e) {
    e.printStackTrace();
    }
    System.out.println("ok");
    }

    public void index() throws Exception {
    /* 创建索引初始化,执行这些语句将创建或清空d:\\save\\目录下所有索引 */
    IndexWriter writer1 = new IndexWriter("d:\\save\\",
    new StandardAnalyzer(), true);
    writer1.close();

    /*
    * 往创建的初始化索引中添加索引内容,StandardAnalyzer表示用lucene自带的标准分词机制,
    * false表示不覆盖原来该目录的索引,细心的读者可能已经发现, 这句话和上面的那句就这个false不一样
    */
    IndexWriter writer2 = new IndexWriter("d:\\save\\",
    new StandardAnalyzer(), false);
    /* 创建一份文件 */
    Document doc1 = new Document();
    /*
    * 创建一个域ArticleTitle,并往这个域里面添加内容 "Field.Store.YES"表示域里面的内容将被存储到索引
    * "Field.Index.TOKENIZED"表示域里面的内容将被索引,以便用来搜索
    */
    Field field1 = new Field("ArticleTitle", "北京2008年奥运会", Field.Store.YES,
    Field.Index.TOKENIZED);
    /* 往文件里添加这个域 */
    doc1.add(field1);
    /* 同理:创建另外一个域ArticleText,并往这个域里面添加内容 */
    Field field2 = new Field("ArticleText", "这是一届创造奇迹、超越梦想的奥运会.......",
    Field.Store.YES, Field.Index.TOKENIZED);
    doc1.add(field2);
    // 在这里还可以添加其他域
    /* 添加这份文件到索引 */
    writer2.addDocument(doc1);

    /* 同理:创建第二份文件 */
    Document doc2 = new Document();
    field1 = new Field("ArticleTitle", "中国获得全球赞誉", Field.Store.YES,
    Field.Index.TOKENIZED);
    doc2.add(field1);
    field2 = new Field("ArticleText", "中国所取得的金牌总数排行榜的榜首........",
    Field.Store.YES, Field.Index.TOKENIZED);
    doc2.add(field2);

    writer2.addDocument(doc2);

    // 在这里可以添加其他文件

    /* 关闭 */
    writer2.close();
    }

    public void search(String serchString) throws Exception {
    /* 创建一个搜索,搜索刚才创建的d:\\save\\目录下的索引 */
    IndexSearcher indexSearcher = new IndexSearcher("d:\\save\\");
    /* 在这里我们只需要搜索一个目录 */
    IndexSearcher indexSearchers[] = { indexSearcher };
    /* 我们需要搜索两个域"ArticleTitle", "ArticleText"里面的内容 */
    String[] fields = { "ArticleTitle", "ArticleText" };
    /* 下面这个表示要同时搜索这两个域,而且只要一个域里面有满足我们搜索的内容就行
    BooleanClause.Occur.MUST表示and,
    BooleanClause.Occur.MUST_NOT表示not,
    BooleanClause.Occur.SHOULD表示or.
    */
    BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,
    BooleanClause.Occur.SHOULD };
    /*
    * MultiFieldQueryParser表示多个域解析,
    * 同时可以解析含空格的字符串,如果我们搜索"中国 金牌",根据前面的索引,显然搜到的是第二份文件
    */
    Query query = MultiFieldQueryParser.parse(serchString, fields, clauses,
    new StandardAnalyzer());
    /* Multisearcher表示多目录搜索,在这里我们只有一个目录 */
    MultiSearcher searcher = new MultiSearcher(indexSearchers);
    /* 开始搜索 */
    Hits h = searcher.search(query);
    /* 把搜索出来的所有文件打印出来 */
    for (int i = 0; i < h.length(); i++) {
    /* 打印出文件里面ArticleTitle域里面的内容 */
    System.out.println(h.doc(i).get("ArticleTitle"));
    /* 打印出文件里面ArticleText域里面的内容 */
    System.out.println(h.doc(i).get("ArticleText"));
    }
    /* 关闭 */
    searcher.close();
    }
    }

    补充内容:
    term
    term是搜索的最小单位,它表示文档的一个词语,term由两部分组成:它表示的词语和这个词语所出现
    的field。
    如:
    Term term1=new Term("date","20090611");
    date即是对应的field:即对应document中的field==> new Field("field名".....)
    20090611即是对应的搜索值.
    (3)
    将索引直接写在内存
    你需要首先创建一个RAMDirectory,并将其传给writer,代码如下:
    Directory dir = new RAMDirectory();
    IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(), true);
    Document doc = new Document();
    doc.add(new Field("title", "lucene introduction", Field.Store.YES, Field.Index.TOKENIZED));
    doc.add(new Field("content", "lucene works well", Field.Store.YES, Field.Index.TOKENIZED));
    writer.addDocument(doc);
    writer.optimize();
    writer.close();
    (4)
    如何删除索引
    lucene本身支持两种删除模式
    1,DeleteDocument(int docNum)
    2,DeleteDocuments(Term term)
    一般使用的是第二种.这种方法实际上是首先根据参数term执行一个搜索操作,然后把搜索到的结果批量
    删除了。我们可以通过这个方法提供一个严格的查询条件,达到删除指定document的目的。
    下面给出一个例子:
    Directory dir = FSDirectory.getDirectory(PATH, false);
    IndexReader reader = IndexReader.open(dir);
    Term term = new Term(field, key);
    reader.deleteDocuments(term);
    reader.close();
    (5)
    如何更新索引
    lucene并没有提供专门的索引更新方法,我们需要先将相应的document删除,然后再将新的document加
    入索引。例如:
    Directory dir = FSDirectory.getDirectory(PATH, false);
    IndexReader reader = IndexReader.open(dir);
    Term term = new Term(“title”, “lucene introduction”);
    reader.deleteDocuments(term);
    reader.close();
    IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(), true);
    Document doc = new Document();
    doc.add(new Field("title", "lucene introduction", Field.Store.YES, Field.Index.TOKENIZED));
    doc.add(new Field("content", "lucene is funny", Field.Store.YES, Field.Index.TOKENIZED));
    writer.addDocument(doc);
    writer.optimize();
    writer.close();

    [2]
    各种各样的Query
    下面我们看看lucene到底允许我们进行哪些查询操作:
    (1)
    TermQuery
    首先介绍最基本的查询,如果你想执行一个这样的查询:“在content域中包含‘lucene’的document”
    ,那么你可以用TermQuery:
    Term t = new Term("content", " lucene";
    Query query = new TermQuery(t);
    (2)
    PhraseQuery
    你可能对中日关系比较感兴趣,想查找‘中’和‘日’挨得比较近(5个字的距离内)的文章,超过这个
    距离的不予考虑,你可以:
    PhraseQuery query = new PhraseQuery();
    query.setSlop(5);
    query.add(new Term("content ", “中”));
    query.add(new Term(“content”, “日”));
    PrefixQuery
    如果你想搜以‘中’开头的词语,你可以用PrefixQuery:
    PrefixQuery query = new PrefixQuery(new Term("content ", "中");
    (3)
    还有:
    BooleanQuery
    WildcardQuery
    FuzzyQuery
    RangeQuery
    (4)
    QueryParser,可以对上面各种query进行整合实现.
    下面我们对应每种Query在QueryParser中演示一下:
    TermQuery可以用“field:key”方式,例如“content:lucene”。
    BooleanQuery中‘与’用‘+’,‘或’用‘ ’,例如“content:java contenterl”。
    WildcardQuery仍然用‘?’和‘*’,例如“content:use*”。
    PhraseQuery用‘~’,例如“content:"中日"~5”。
    PrefixQuery用‘*’,例如“中*”。
    FuzzyQuery用‘~’,例如“content: wuzza ~”。
    RangeQuery用‘[]’或‘{}’,前者表示闭区间,后者表示开区间,例如“time:[20060101 TO
    20060130]”,注意TO区分大小写。
    你可以任意组合query string,完成复杂操作.
    如:
    Directory dir = FSDirectory.getDirectory(PATH, false);
    IndexSearcher is = new IndexSearcher(dir);
    QueryParser parser = new QueryParser("content", new StandardAnalyzer());
    Query query = parser.parse("+(title:lucene content:lucene) +time:[20060101 TO 20060130]";
    Hits hits = is.search(query);
    即表示:
    标题或正文包括lucene,并且时间在20060101到20060130之间的文章.

    (5)
    Filter
    filter的作用就是限制只查询索引的某个子集,它的作用有点像SQL语句里的 where,但又有区别,它不是正规查询的一部分,只是对数据源进行预处理,然后交给查询语句。注意它执行的是预处理,而不是对查询结果进行过滤,所以使用filter的代价是很大的,它可能会使一次查询耗时提高一百倍。
    最常用的filter是RangeFilter和QueryFilter。RangeFilter是设定只搜索指定范围内的索引;QueryFilter是在上次查询的结果中搜索。
    Filter的使用非常简单,你只需创建一个filter实例,然后把它传给searcher。继续上面的例子,查询“时间在20060101到20060130之间的文章”除了将限制写在query string中,你还可以写在RangeFilter
    中:
    Directory dir = FSDirectory.getDirectory(PATH, false);
    IndexSearcher is = new IndexSearcher(dir);
    QueryParser parser = new QueryParser("content", new StandardAnalyzer());
    Query query = parser.parse("title:lucene content:lucene";
    RangeFilter filter = new RangeFilter("time", "20060101", "20060230", true, true);
    Hits hits = is.search(query, filter);
    (6)
    Sort
    有时你想要一个排好序的结果集,就像SQL语句的“order by”,lucene能做到:通过Sort。
    Sort sort Sort(“time”); //相当于SQL的“order by time”
    Sort sort = new Sort(“time”, true); // 相当于SQL的“order by time desc”
    下面是一个完整的例子:
    Directory dir = FSDirectory.getDirectory(PATH, false);
    IndexSearcher is = new IndexSearcher(dir);
    QueryParser parser = new QueryParser("content", new StandardAnalyzer());
    Query query = parser.parse("title:lucene content:lucene";
    RangeFilter filter = new RangeFilter("time", "20060101", "20060230", true, true);
    Sort sort = new Sort(“time”);
    Hits hits = is.search(query, filter, sort);

    (7)
    优化搜索性能
    由以上数据可以得出结论:
    1、 尽量降低时间精度,将精度由秒换成天带来的性能提高甚至比使用cache还好,最好不使用filter。
    2、 在不能降低时间精度的情况下,使用cache能带了10倍左右的性能提高。

    Lucene的中文分词器(PaodingAnalyzer)+高亮显示
    [1]
    分词功能介绍
    分词模块对于搜索是很重要的。搜索其实就是对分词的每一个片段进行查询,检查是否匹配.
    (1)
    Lucene版本是lucene-2.4.0,它(如standardAnalyzer)已经能够支持中文分词,但它是采用一元分词(逐字拆分)的方法,即把每一个汉字当作是一个词,这样会:
    使建立的索引非常庞大,
    检索缓慢,
    同时查询的准确性不高,会影响查询效率.
    如:
    字符串"中华为何怎么做",用standardAnalyzer一元切词,结果如下:
    中 华 为 何 怎 么 做
    当我们想查询"华为"时,"华为"分为"华 为",分别与上面的"华 为"相匹配.但这不是我们想查询的结果.
    又如:搜索“和服”会出现“产品和服务”,搜索“海尔”会出现“海尔德”.
    所以有必要给文本增加词的边界信息以提高检索精确度。这里我就介绍最为常用的"庖丁解牛" 分词包.
    (2)
    对于英语分词
    以单词之间的间隔来划分.
    无论是standardAnalyzer,PaodingAnalyzer,英文的切词,一个连接的单词,不会被切成两分.如:
    AttachFileSize,只能切为AttachFileSize;
    Attach File Size,会被切成Attach File Size
    若要用Attach去查找AttachFileSize,则须用通配符.
    而中文切词上:如:"中华为何怎么做"
    standardAnalyzer:一元切词(如:中 华 为 何 怎 么 做)
    PaodingAnalyzer:二元切词(如:中华 华为 为何 怎么 做 )

    (3)
    安装"庖丁解牛"分词包:
    庖丁中文分词需要一套词典,这些词典需要统一存储在某个目录下,这个目录称为词典安装目录。词典安装目录可以是文件系统的任何目录,它不依赖于应用程序的运行目录。将词典拷贝到词典安装目录的过程称为安装词典。增加、删除、修改词典目录下的词典的过程称为自定制词典。
    其安装的方法:
    1.
    "庖丁解牛"的下载地址是http://code.google.com/p/paoding/downloads/list,下载好后解压,我解压在E:\paoding2_0_4;
    2.
    进入该目录,首先将paoding-analysis.jar拷贝到项目的WEB-INF/lib目录;
    3.
    接着需要设置环境变量PAODING_DIC_HOME,变量名:PAODING_DIC_HOME 变量值:E:\paoding2_0_4\dic
    4.
    第三步将E:\paoding2_0_4\src目录下的paoding-dic-home.properties属性文件拷贝到项目的src目录下(注意是src的根目录下),添加一行aoding.dic.home=E:/paoding2_0_4/dic.
    好了,到这里,已经完成了Lucene和"庖丁解牛"的整合.
    (4)
    查看各种分词器的分词情况:
    public static void main(String[] args) throws Exception {
    //StandardAnalyzer: 一元分词
    //Analyzer analyzer = new StandardAnalyzer();
    //PaodingAnalyzer: 二元分词
    Analyzer analyzer = new PaodingAnalyzer();
    String indexStr = "我的QQ号码是58472399";
    StringReader reader = new StringReader(indexStr);
    TokenStream ts = analyzer.tokenStream(indexStr, reader);
    Token t = ts.next();
    while (t != null) {
    System.out.print(t.termText()+" ");
    t = ts.next();
    }
    }
    StandardAnalyzer分词结果:我 的 qq 号 码 是 58472399
    PaodingAnalyzer分词结果:我的 qq 号码 58472399
    如果把indexStr换成是"中华人民共和国万岁" ,那么分词结果为:
    中华 华人 人民 共和 共和国 万岁
    很明显,它的分词效果要比Lucene自带的中文分词器的效果好的多.Lucene自带分词器是将中文逐字拆分的,这是最为原始的分词方法,现在大都不采用.

    [2]
    关键字高亮显示
    关键字高亮显示也就是在页面显示时,事先对要显示的内容处理,抽取出关键字并加亮,这里抽取关键字也是用lucene,lucene自带有heightlight包就可以实现此功能。
    Highlighter包括了三个主要部分:段划分器(Fragmenter)、计分器(Scorer)和格式化器(Formatter)。
    通常要用到的几个重要类有:
    import org.apache.lucene.search.highlight.Highlighter;
    import org.apache.lucene.search.highlight.QueryScorer;
    import org.apache.lucene.search.highlight.SimpleFragmenter;
    import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
    1)SimpleFragmenter
    Highlighter利用Fragmenter将原始文本分割成多个片段。内置的SimpleFragmenter将原始文本分割成相同大小的片段,片段默认的大小为100个字符。这个大小是可控制的。
    2)SimpleHTMLFormatter:用来控制你要加亮的关键字的高亮方式
    此类有2个构造方法
    1:SimpleHTMLFormatter()默认的构造方法.加亮方式:关键字
    相当于如下代码:
    Formatter formatter = new Formatter() {
    public String highlightTerm(String srcText, TokenGroup g) {
    if (g.getTotalScore() <= 0) {
    return srcText;
    }
    return "" + srcText + "";
    }
    };
    2:SimpleHTMLFormatter(String preTag, String postTag).加亮方式:preTag关键字postTag
    3)QueryScorer
    QueryScorer 是内置的计分器。计分器的工作首先是将片段排序。QueryScorer使用的项是从用户输入的查询中得到的;它会从原始输入的单词、词组和布尔查询中提取项,并且基于相应的加权因子(boost factor)给它们加权。
    为了便于QueryScoere使用,还必须对查询的原始形式进行重写。比如,带通配符查询、模糊查询、前缀查询以及范围查询 等,都被重写为BoolenaQuery中所使用的项。在将Query实例传递到QueryScorer之前,可以调用Query.rewrite (IndexReader)方法来重写Query对象.
    [3]
    实例之
    使用Lucene+Paoding构建SSH2系统的站内搜索
    说明:
    (1)
    用paodingAnalyzer进行分词的操作,与用standardAnalyzer几乎一样,只是:
    在创建索引时:

    IndexWriter writer = new IndexWriter(indexPath,new PaodingAnalyzer(), true);
    代替:
    IndexWriter writer = new IndexWriter(indexPath,new StandardAnalyzer(), true);
    用:
    doc.add(new Field
    ("id",id,Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
    代替:
    doc.add(new Field("id",id,Field.Store.YES,Field.Index.TOKENIZED));
    在搜索时,
    用:
    QueryParser parser = new QueryParser("id",new PaodingAnalyzer());
    代替:
    QueryParser parser = new QueryParser("id",new StandardAnalyzer());
    如下:
    public static Document createConfigDoc(String id,String confContext)
    {
    Document doc=new Document();
    //采用默认的standardAnalyzer
    // doc.add(new Field("id",id,Field.Store.YES,Field.Index.TOKENIZED));
    // doc.add(new Field
    ("confContext",confContext,Field.Store.YES,Field.Index.TOKENIZED));
    //采用paodingAnalyzer
    doc.add(new Field
    ("id",id,Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
    doc.add(new Field
    ("confContext",confContext,Field.Store.YES,Field.Index.TOKENIZED,Field.TermVector.WITH_POSI
    TIONS_OFFSETS));
    return doc;
    }
    (2)
    对于高亮显示:请见代码;
    如下:
    try {
    IndexReader reader = IndexReader.open(indexPath);
    IndexSearcher searcher = new IndexSearcher(indexPath);
    QueryParser parser = new QueryParser("id",analyzer);
    Query query=parser.parse(searchMess);
    query = query.rewrite(reader);
    System.out.println("Searching for: " + query.toString());
    hits=searcher.search(query);

    String SearchMess="";
    String SearchValue="";
    for (int i = 0; i < hits.length(); i++)
    {
    String highLightText="";
    Document doc = hits.doc(i);
    SearchMess=doc.get("id");
    SearchValue=doc.get("confContext");
    System.out.println("-----高亮前------SearchMess:\n\t" +
    SearchMess);
    // 设置高亮
    SimpleHTMLFormatter formatter = new SimpleHTMLFormatter
    ("", "");
    Highlighter highlighter = new Highlighter(formatter, new
    QueryScorer(query));
    //Highlighter利用Fragmenter将原始文本分割成多个片段。片段默
    认的大小为100个字符。
    //设置每一片段的大小
    highlighter.setTextFragmenter(new SimpleFragmenter(200));
    if (SearchMess != null) {
    //id:为上面查询分析器中设置查询的项:QueryParser
    parser = new QueryParser("id",analyzer);
    //SearchMess:为上面查询结果中的内容:Document doc =
    hits.doc(i);SearchMess=doc.get("id");
    //若设置出错,则高亮显示为null
    TokenStream tokenStream = analyzer.tokenStream("id",new
    StringReader(SearchMess));
    //highLightText,则是高亮显示的结果.下面的highLightText,输出
    格式如:
    //中华为何
    highLightText = highlighter.getBestFragment
    (tokenStream,SearchMess);
    v.add(highLightText);
    v.add(SearchValue);
    System.out.println("-----高亮后------highLightText:\n\t" +
    highLightText);
    }
    }
    searcher.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    (3)
    对于创建索引,与搜索过程:
    创建索引,
    (若搜索文件比较小,也可是:创建索引-->进行搜索.但一般情况下,采用创建索引,与搜索过程分离.如下)
    我们可以利用Quartz在夜间自动重新创建lucene最新的index,从而保证索引内容与数据库中的内容相对
    比较一致(相当于旧索引的更新.因为用户可能会修改原记录的内容,所以索引对应的内容也应该被相应的更新);
    当用户进行搜索时,我们进行:
    当用户进行搜索时,可以设置"增量索引"的方式,把新增的DB记录追加到索引文件中,从而保证用户最新的消息可以被搜索到.
    然后再进行搜索操作.
    如下:
    增量索引方式,可以如上面的实现那样设置;这里只列出定时创建索引代码:
    创建索引代码:
    public void createLuceneIndex()
    {
    String idPath="D:/tomcat_bbs/webapps/BBSCS_8_0_3/storeId.txt";
    String indexPath="D:/tomcat_bbs/webapps/BBSCS_8_0_3/index";
    try {
    //for iBatis
    List bbsConfigs = (List) sqlMapClientTemplate.queryForList
    ("getAllBBSConfig");
    //IndexWriter writer = new IndexWriter(indexPath,new
    StandardAnalyzer(), true);
    IndexWriter writer = new IndexWriter(indexPath,new PaodingAnalyzer
    (), true);
    for (int a = 0; a < bbsConfigs.size(); a++) {
    BBSConfig bbsConfig = (BBSConfig) bbsConfigs.get(a);
    Document doc = JLuceneUtils.createConfigDoc
    (bbsConfig.getId(), bbsConfig.getConfContext());
    writer.addDocument(doc);
    }
    writer.optimize(); //优化索引文件
    writer.close();
    System.out.println("-------------定时创建lucene的Indexe success!");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    定时代码:


    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">




    createLuceneIndex



    class="org.springframework.scheduling.quartz.CronTriggerBean">




    0 0 4 * * ?




    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">





    -->此处



    (4)
    最后调用后,将highLightText放于session中,通过return 'search';返回到前台,再获取显示.因为是前台是HTML/JSP页面,所以,如:highLightText="中华为何",就会显示出高亮效果.若用system.out打印,则只能看到:
    中华为何



    原文地址:http://www.lingcn.com/Blogs/bb6484e9-0611-47ac-8484-ab20046d5389.aspx
    展开全文
  • Lucene笔记+PaodingAnalyzer+高亮显示

    千次阅读 2010-08-25 11:55:00
      [1] (1) Lucene是一个基于Java全文搜索引擎,利用它可以...也就是说不管是MS word, Html ,pdf还是其他什么形式的文件只要你可以从中抽取出文字形式的内容就可以被Lucene所用。 (3)<b
  • [1] (1) Lucene是一个基于Java全文搜索引擎,利用它可以轻易地为Java软件加入全文搜寻功能。...也就是说不管是MSword, Html ,pdf还是其他什么形式的文件只要你可以从中抽取出文字形式的内容就可以被
  • highlighter高亮检索详解 参考官网https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html#highlighting-settings 什么是highlight Highlight您能够从搜索结果中的...
  • 使用word

    2019-10-03 06:01:29
    同样这也是生活中常用到的办公软件,word本质是一个排版软件,它与一般的编辑器不同的是,它将整个文本分成了一页一页的,当然这也是方便于打印文档。 使用word还是很容易的,一般来说需要注意以下几方面的问题: ...
  • vim之高亮关键字,立时查找字符 2011-10-28 16:11 1046人阅读 评论(0) 收藏 举报 查找字符 命令f用于在本行内向前搜索。例如fx是向前(Forward)搜索字母x。而命令F是向后(Backward)搜索。例如...
  • notepad++ 去除 重复

    万次阅读 2013-11-22 11:30:26
    例如1:去除重复行 先安装TextFx插件 在菜单TextFX-->TextFX Tools下面进行操作 1 确定“sort outputs only unique” 该选项 已经选择 2 选择要去除重复行的文本 3 选择sort lines case sensitive" 或者
  • 然后会发现有重复的字体,将活跃的字体都改为“访问”一为“用户”的字体: 重启Microsoft Office for Mac,此时不会出现字体缺失的问题了,字体显示也为Windows下的状态。 2.在macOS下编辑文档注意字体的使用,...
  • Word XPWord XP 中目录的编制方法 1.单击要插入目录的位置。 2.指向"插入"菜单上的"引用",再单击"索引和目录"。 3.单击"目录"选项卡。 4.若要使用现有的设计,请在"格式"框中单击进行选择。 5.根据需要,选择...
  • vim 配置文件 ,高亮+自动缩进+行号+折叠+优化 http://apps.hi.baidu.com/share/detail/31767352 将一下代码copy到 用户目录下 新建文件为 .vimrc 保存即可生效; 如果想所有用户生效 请修改 /etc/vimrc
  • 第七周 Word文档修订

    2013-08-15 23:49:00
    come from:http://www.sxszjzx.com/~c20/12-2/office-gj/ 第七周 Word文档修订 教学时间 2013-4-8 教学课时 2 教案序号 12 教学目标 1、学会添加、修改、删除批注,学会设置批注的样式2、学会使用修订标记,学会...
  • 论文写作中word操作

    千次阅读 2013-02-25 12:06:59
    WORD2003 1、将光标定位于需要开始编页码的页首位置。  2、选择“插入-分隔符”,打开“分隔符”对话框,在“分隔符类型”下单击选中(分节符)“下一页”单选钮,分隔符的作用是对每一章分页,比如第二章另起一...
  • word应用2(实用)

    千次阅读 2014-05-21 22:04:36
    1、快速改变Word文档的行距 选中你需要设置行距的文本段落,按“Ctrl+ 1”的组合键,即可将段落设置成单倍行距;按“Ctrl+ 2”的组合键,即可将段落设置成双倍行距;按“Ctrl+5”的组合键,即可将段落设置成1.5倍...
  • 如何使用 word2vec 来做推荐系统

    千次阅读 2019-08-09 18:00:00
    点击上方“AI派”,选择“设为星标”最新分享,第一时间送达!译者 | Arno来源 | Analytics Vidhy这篇文章主要介绍了如何使用word2vec构建推荐系...
  •   ...excel 2007 删除重复项 / EXCEL怎么删除重复项 http://jingyan.baidu.com/article/46650658756e10f549e5f8a7.html  excel 2007 数据查找比对 http://beside.iteye.com/blog/311132 ...
  • word项目符号或编号bullets and numbering

    千次阅读 2012-03-27 16:48:36
    本文提供了如何在 Word 中创建项目符号或编号列表的分步摘要。 在 Word,您可以将项目符号添加到现有的文本,行,或在键入时,可以自动创建项目符号列表。若要使用这些方法的任一,请根据您的具体情况使用下面的...
  • word 页码 罗马数字怎么从1开始第一步:在前几页结束的地方点“插入”——>“分隔符”作用是区别前几页和正文的内容;第二步:点击“视图”——>“页眉和页脚”你就能看到页眉和页脚了;还有页眉和页脚的设置...
  • vim 删除重复部分的行 vim 技巧

    千次阅读 2018-10-13 19:32:33
    vim 删除重复部分的行 vim 技巧 g/\%(^\1\&gt;.*$\n\)\@&lt;=\(\k\+\).*$/d 重复的部分不是全行,而是kerword部分(:h 'iskeyword'),遇到空格,-什么的就终止,   搜索 /joe/e : 设置光标到匹配"...
  • hello os环境准备 Bochs NASM 第一行汇编 boost.asm 在屏幕打印hello os org 07c00h ;指定代码加载到7c00地址处mov ax, cs ...显示字符串 jmp $ ;无线循环DispStr: mov ax, BootMessage mov bp, ax ;es:bp
  • source insight 常用...shift + F8 快捷键也可以双击先选中,然后鼠标右键,点击 Highlight Word,就是高亮显示重复此操作即可取消高亮显示整个工程中同名的变量都会高亮显示的。 退出程序 : Alt+F4 重画屏幕
  • 封面 目录不要页码 从第三页正文开始要页码的 设置 方法 1.鼠标放在正文页(即你的第三页)首行之前,点击“插入”-“分隔...2.把鼠标定位正文第一页,点击“视图”-“页眉和页脚”显示“页眉和页脚”工具栏。  3

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,342
精华内容 1,736
关键字:

word高亮显示重复项