精华内容
下载资源
问答
  • word索引项
    2019-02-25 12:00:05
    使用WORD的索引功能(转)

      索引是根据一定需要,把书刊中的主要概念或各种题名摘录下来,标明出处、页码,按一定次序分条排列,以供人查阅的资料。它是图书中重要内容的地址标记和查阅指南。设计科学编辑合理的索引不但可以使阅读者倍感方便,而且也是图书质量的重要标志之一。WORD就提供了图书编辑排版的索引功能,现将其使用方法介绍如下:

        如何标记文档中的索引项

      要编制索引,应该首先标记文档中的概念名词、短语和符号之类的索引项。索引的提出可以是书中的一处,也可以是书中相同内容的全部。如果标记了书中同一内容的所有索引项,可选择一种索引格式并编制完成,此后 Word 将收集索引项,按照字母顺序排序,引用页码,并会自动查找并删除同一页中的相同项,然后在文档中显示索引。以标记文中的“唯物主义”为例,先用鼠标选定文中“唯物主义”四字,然后执行“插入”菜单下的“索引和目录”,出现对话框后,选择“标记索引项”,出现下一个对话框后,选择“标记”最后执行“关闭”这时在原文中的“唯物主义”二字后面将会出现“{XE "唯物主义"}”的标志,按一下工具栏上的“显示/隐藏”按钮,可把这一标记隐藏或显示出来。如果你要把本书中所有的出现“唯物主义”的地方索引出来,可在出现第二个对话框后,执行“标记全部”,这样全书中凡出现“唯物主义”的页面都会被标记出来。索引的格式可自行选择,排序方式有“笔划”和“拼音”两种,默认项是“笔划”。

        如何提出已标记的索引项

      当做完上面的索引标记之后, 就可以提取所标记的索引了,其方法是,把光标移到书的最后 边,然后执行“插入”菜单下的“索引和目录”,此时,一个索引就出现在光标处,如果你当初选择的是“标记全部”,则索引会标记出你所索引的某个词都出现在哪一页上。一个索引词在同一页 中出现多次,索引为节省页面,只会标记一次,并按笔画或拼音进行了排序。这样你就可以按照索引的提示查找有关页面的内容了。

      如果你要对生成的的索引格式进行编辑调整可在索引对话框中对有关项目进行选择、自定义或更改。通过选择相应的选项卡,选择不同的索引格式。

    如何将@、*、¥之类的符号标记为索引项

      首先选定文档中的单个符号。然后执行索引命令,在出现的对话框中的“主索引项”框中,紧随此符号键入“;#”,最后单击“标记”按钮。编制索引时,Word 将符号放在索引的开始部份。如果所选索引格式包含用于字母组的标题,则符号将归为一组,置于数字标志 # 标题之下。既可以删除该数字符号,也可用“符号”等其他标题来替换它。

        如何更新索引、目录

      一般情况下,要在输入全部文档内容之后再进行索引工作,如果此后又进行了内容的修改,原索引就不准确了,这就需要更新索引,其方法是,在要更新的索引中单击鼠标,然后按 F9 键。在更新整个索引后,将会丢失更新前完成的索引或添加的格式。

      如何处理索引的页码和文档中的页码不相符,如果出现这种情况。可单击索引后再按 F9 键, 即可对其进行更新。

      如果进行了索引之后,文档中显示 XE 或 TA 域等隐藏文字,请单击“显示/隐藏”按钮可将隐藏,然后更新索引。如果文档包含以隐藏文字格式出现的分节符或分页符,则请删除隐藏文字格式,然后更新索引,这样页面显示就清晰美观了。

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14102/viewspace-115506/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/14102/viewspace-115506/

    更多相关内容
  • Word2021标记索引项和索引的生成.docx
  • Word制作索引

    2012-08-14 14:07:18
    Word制作索引 Word书籍制作技巧 Word中常用的方法
  • 以下的文章主要介绍的是MySQL索引的缺点以及MySQL索引在实际操作中有哪些事项是值得我们大家注意的,我们大家可能不知道过多的对索引进行使用将会造成滥用,需要的朋友可以了解下
  • 投寄箱搜寻索引并搜索存储在Dropbox中的文档内容。 需要node.js和Solr,支持许多文档类型和关键字快捷方式,并在添加或编辑文件时更新索引。... npm install下载依赖(solr,dbox,express,dateformat)。 node inde
  • ik_max_word最细密度的拆分文本,会穷尽各种组合,适用于Term Query ik_smart最粗密度的拆分文本,适合Phrase查询 文档经过ik分词器生成倒排索引 (字符串两种text类型分词,keyword不分词(barcode条码)) ik分词器有...

    ES中put 新增 post 修改

    Kibana开发工具,用来往ES引擎中对文档进行操作和生成文档的对应索引的

    ik_max_word最细密度的拆分文本,会穷尽各种组合,适用于Term Query

    ik_smart最粗密度的拆分文本,适合Phrase查询

    文档经过ik分词器生成倒排索引 (字符串两种text类型分词,keyword不分词(barcode条码))

    ik分词器有自己的词典存有百万计的中文词,分出的词段与字典匹配,字典有就保留

    索引(是具有实现关键词-文档矩阵的具体数据结构的数据)(里面存储着各种具体储存类型的索引)

    索引可进行分片存储在多个服务器上,提高效率,分片可以行成副本,以防止服务器宕机导致搜索数据不全,副本可以是n个,是根据服务器的多少,和自身需求来定(一般就两三个 ),一个分片的副本在其他服务器上每个只有一份

    put创建索引,实质put请求http ,其实索引生成器有两步操作,其实put(新增)请求上面的路径是在往url里添加文档原始数据,put/products/Id这个id就是这个文档id, 还有索引生成器对提交的文档创建相应的索引,索引id就是文档id

    索引库:储存搜索引擎抓取到的相应的资源(文档等) 还有索引

    正向索引:  当用户发起查询时(假设查询为一个关键词),搜索引擎会扫描索引库中的所有文档,找出所有包含关键词的文档,这样依次从文档中去查找是否含有关键词的方法叫做正向索引。

    正向索引数据的数据结构:文档id->关键词

    倒排索引(反向索引 )(Inverted Index): 倒排索引数据的数据结构是 关键词->文档或者网页id的矩阵的具体数据结构,是关键词-文档矩阵的具体存储结构之一

    倒排索引由"词典"和倒排文件组成,根据词典中的关键词获取相应的倒排列表

    词典(Lexicon): 搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。(存在于内存中)

    倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。

    倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。

    倒排列表中除了存储文档Id外还有TF(term frequency): 单词在文档中出现的次数。Pos: 单词在文档中出现的位置。(倒排列表(DocID;TF;<Pos>))

    文档(Document):一般搜索引擎的处理对象是互联网网页,而文档这个概念要更宽泛些,代表以文本形式存在的存储对象,相比网页来说,涵盖更多种形式,比如Word,PDF,html,XML等不同格式的文件都可以称之为文档。

    文档集合(Document Collection):由若干文档构成的集合称之为文档集合。比如海量的互联网网页或者说大量的电子邮件都是文档集合的具体例子。

    文档编号(Document ID(Doc ID)):在搜索引擎内部,会将文档集合内每个文档赋予一个唯一的内部编号,以此编号来作为这个文档的唯一标识,这样方便内部处理,每个文档的内部编号即称之为“文档编号”,后文有时会用DocID来便捷地代表文档编号。es中文档编号就是文档创建对应的索引编号,

    单词编号(Word ID):与文档编号类似,搜索引擎内部以唯一的编号来表征某个单词,单词编号可以作为某个单词的唯一表征。

    词条:一段文本中有效词的子序列,其中每个子序列称为一个词条。(文本词条化,去掉停用词)(就是关键词)

    词条类:相同词条构成的集合。  

    词项:一个词项指的是在信息检索系统词典中所包含的某个可能经过归一化处理的词条类。(词项集合和词条集合可以完全不同,比如可以采用某一个分类体系中的类别标签作为词项。当然,在实际的信息检索系统中,词项往往和词条密切相关)

    停用词(stop word): 某些情况下,一些常见词在文档和用户需求进行匹配时价值并不大,需要彻底从词汇表中去除。这些词称为停用词(stop word).

    去掉停用词:  一个常用的生成停用词表的方法就是将词项按照文档集频率(collection frequency,每个词项在文档集中出现的频率)从高到低排列,然后手工选择那些语义内容与文档主题关系不大的高频词作为停用词。停用词表中的每个词将在索引过程中被忽略.

    中文和英文等语言不同,单词之间没有明确分隔符号,所以首先要用分词系统将文档自动切分成单词序列。这样每个文档就转换为由单词序列构成的数据流,为了系统后续处理方便,需要对每个不同的单词赋予唯一的单词编号,同时记录下哪些文档包含这个单词,在如此处理结束后,我们可以得到最简单的倒排索引.

    修改文档

    底层的索引数据无法修改,修改数据实际上是删除在重新添加

    put: 对文档进行完整的替换

    post: 可以修改一部分字段这两种方法实质上还是先删除在添加

    删除文档

     

    redis 加速   mongodb 加速 算法关系 运算  es 搜索

    在创建索引工具查看上生成的索引 第一个看不到分词器生成的关键词

    后面的三个是能查看fields后面对应的数据被分词器生成的关键词

    在post后面的路径搜索相关的关键词 query中是搜索参数 match_all全部后面不加参数,match加参数就是指定的数据  size 是返回显示的数据参数个数:如果不设置默认返回十个

     

    bool是判断,must是与,should是或,match是搜索参数(可以是具体关键词,也可以是数量)

    filter是过滤,range代表价格过滤类别

    关键词高亮处理

                             

     fields [选择查找关键词的字段]       highlight是高亮设置 pre_tags是关键词的标签前部分

                                                            post_tags是后部分fields是指定关键词做高亮的字段

    ..

     Spring Data Elasticsearch

    添加依赖elasticsearch

    ngram分词器分词原理如图

                                                         

     这段是ngram分词器的官方配置

    Repository API

    package cn.tedu.es;
    
    import cn.tedu.es.entity.Student;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    import java.util.List;
    
    /*
    Spring Data Repository 规范
        只需要定义抽象接口、抽象方法,不需要自己实现,
        Repository 底层代码已经实现了所有的数据操作代码
     */
    public interface StudentRepository//泛型里的参数是,操作的数据的类型和索引id类型 
            extends ElasticsearchRepository<Student, Long> {
    
        // 在 name 中搜索关键词
        Page<Student> findByName(String nameKey, Pageable pageable);
    
        // 在 name 和 birthDate 中搜索
        List<Student> findByNameOrBirthDate(String name, String birthDate);
    
    }
    配置文件--日志
    logging:
      level:
        # 显示 rest api 通信的 http 协议数据
        tracer: trace  
    package cn.tedu.es.entity;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    
    /*
    @Document 用来指定索引
              也可以用来自动创建索引,
              一般索引是自己手动创建   shards是分片数量   replicas是副本
     */
    @Document(indexName = "students",shards = 3,replicas = 2)
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
        @Id  //     使用学生学号,作为索引id(_id) 不加随机产生
        private Long id;
        private String name;
        private Character gender;
        // 设置索引中的字段名,对应实体类中的属性
        // 字段名和属性名相同,可以省略
        @Field("birthDate")
        private String birthDate;
    }

     Criteria API

    Criteria
    Criteria --封装搜索条件   CriteriaQuery --封装了Criteria
    SearchOperation --执行上面的Query请求工具
    package cn.tedu.es;
    
    import cn.tedu.es.entity.Student;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
    import org.springframework.data.elasticsearch.core.SearchHit;
    import org.springframework.data.elasticsearch.core.SearchHits;
    import org.springframework.data.elasticsearch.core.query.Criteria;
    import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @Component
    public class StudentSearcher {
        // 用来执行 CriteriaQuery 的工具对象
        @Autowired
        private ElasticsearchOperations o;
    
        // 任意定义的搜索方法
        public List<Student> findByName(String nameKey) {
            Criteria c = new Criteria("name"); //字段
            c.is(nameKey); //关键词
            return exec(c);
        }
        public List<Student> findByBirthDate(String from, String to) {  //from to是一个数值到另一个数值
            Criteria c = new Criteria("birthDate");
            c.between(from, to);
            return exec(c);
        }
    
        private List<Student> exec(Criteria c) {
            // 把条件,封装到一个查询对象
            CriteriaQuery q = new CriteriaQuery(c);
            // SearchHits[SearchHit<Student>, SearchHit<Student>, SearchHit<Student>]
            SearchHits<Student> shs = o.search(q, Student.class);
    
            // List<Student> list = new ArrayList<>();
            // for (SearchHit<Student> sh : shs) {
            //     Student s = sh.getContent();
            //     list.add(s);
            // }
    
            // 可以使用集合的 stream api 和 lambda 语法,简化上面的代码
            List<Student> list =
                    shs.stream()
                        .map(SearchHit::getContent)
                        .collect(Collectors.toList());
    
            return list;
        }
    }
       @Test
        public void test3() {
            Optional<Student> o1 = r.findById(9533L);
            if (o1.isPresent()) { // 防止student是null
                Student stu = o1.get();
                System.out.println(stu);
            }
    //Optional封装了Student实例,防止出现空指针异常,student类型的o1是null,经过封装得到Optional实例o1,
    //即使被封转的是null值,o1也是实例对象

     Spring Data ES分页

    Pageable --是封装向服务器提交的分页参数 (页号 和 页里的数据段数目)
    Page  --(可选配置)封装从服务器中返回的搜索结果的一页数据,和分页属性数据(分页属性数据包括number(当前页的页号) hasPrevious(是否有上页) hasNext(是否右下一页) rows数据行数 maxPage最大页页号)
    //Repository api
    
    Page<Student> findByName(String nameKey, Pageable pageable)
    //Page也可以用List代替没有严格要求    
    ...
    Pageable p = PageRequest.of(0, 20);//第一个参数是页数,第二个参数是条数
    r.findByName("华", p)
    package com.pd.controller;
    
    import com.pd.pojo.Item;
    import com.pd.service.SearchService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.elasticsearch.core.SearchHit;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import sun.awt.util.IdentityLinkedList;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Controller
    public class SearchController {
        @Autowired
        private SearchService searchService;
    
        //   /search/toSearch.html?key=手机&page=1&size=20 这里的参数不能用pagenumber和pagesize
        //直接接收,都由pageable接收
        @GetMapping("/search/toSearch.html")
        public String search(Model model, String key, Pageable pageable) {
            // Model 是用来向界面传递数据动工具
            List<SearchHit<Item>> list = searchService.search(key, pageable);
    
            List<Item> items = new ArrayList<>();
            for (SearchHit<Item> sh : list) {
                Item it = sh.getContent();
                String title = hlTitle(sh.getHighlightField("title")); //高亮的title
                it.setTitle(title); // item中原始title替换成高亮的title
                items.add(it);
            }
    
            model.addAttribute("items", items);
            model.addAttribute("page", pageable);
            // pageable.getPageNumber()
            // pageable.getPageSize()
    
            return "/search.jsp";
        }
    
        private String hlTitle(List<String> title) {
            StringBuilder sb = new StringBuilder();
            for (String s : title) {
                sb.append(s);
            }
            return sb.toString();
        }
    }

    高亮显示

    //Repository api 高亮显示结果 SearchHit,只能用 List 存放,不能用 Page,
    
    //会缺少分页属性
    
        @Highlight(
            parameters = @HighlightParameters(//便签
                preTags = "<em>",//前置
                postTags = "</em>"//后置
                ),
            fields = {//字段名
                @HighlightField(name = "name"),
                @HighlightField(name = "summary")
        })
        List<SearchHit<Item>> findByNameOrSummary(String text, String summary);

    词条归一化(token normalization):  就是将看起来不完全一致的多个词条归纳成一个等价类,以便在它们之间进行匹配的过程.

    隐式地建立等价类,每类可以用其中的某个元素来命名。比如,在文档和查询中,都把词条anti-discriminatory和antidiscriminatory映射成词项antidiscriminatory,这样对两个词中的任一个进行搜索,都会返回包含其中任一词的文档。这种处理方法的优点在于:一方面,等价类的建立过程是隐式的,不需要事先计算出等价类的全部元素,在映射规则下输出相同结果的词项一起构成等价类集合;另一方面,仅仅构建“去除字符”这种映射规则也比较容易.

    显示建立等价类,维护多个非归一化词条之间的关联关系。该方法可以进一步扩展成同义词词表的手工构建,比如将car和automobile归成同义词。这些词项之间的关系可以通过两种方式来实现。第一种常用的方式是采用非归一化的词条进行索引,并为某个查询词项维护一张由多个词组成的查询扩展词表。当输入一个查询词项时,则根据扩展词表进行扩展并将扩展后得到的多个词所对应的倒排记录表合在一块(如下图一)。另一种方式是在索引构建时就对词进行扩展(如下图二)。比如,对于包含automobile的文档,我们同时也用car来索引(同样,包含car的文档也用automobile来索引).

    文档频率信息”代表了在文档集合中有多少个文档包含某个单词,之所以要记录这个信息,其原因与单词频率信息一样,这个信息在搜索结果排序计算中是非常重要的一个因子.            

    展开全文
  • 倒排索引 倒排索引
  • 主索引通常是对每一存储块有一个索引项索引项的总数和存储表所占的存储块数目相同,存储表的每一存储块的第一条记录,又称为锚记录(anchor record), 或简称为块锚(block anchor) 主索引的索引字段值为块锚的索引...

    1.主索引

    主索引通常是对每一存储块有一个索引项,索引项的总数和存储表所占的存储块数目相同,存储表的每一存储块的第一条记录,又称为锚记录(anchor record), 或简称为块锚(block anchor)

    • 主索引的索引字段值为块锚的索引字段值,而指针指向其所在的存储块。
    • 主索引是按索引字段值进行排序的一个有序文件, 通常建立在有序主文件的基于主码的排序字段上,即主索引的索引字段与主文件的排序码(主码)有对应关系
    • 主索引是稀疏索引
      在这里插入图片描述

    2.辅助索引

    辅助索引 是定义在主文件的任一或多个非排序字段上的辅助存储结构。

    • 辅助索引通常是对某一非排序字段上的每一个不同值有一个索引项:索引字段即是该字段的不同值,而指针则指向包含该记录的块或该记录本身;
    • 当非排序字段为索引字段时,如该字段值不唯一,则要采用一个类似链表的结构来保存包含该字段值的所有记录的位置。
    • 辅助索引是稠密索引,其检索效率有时相当高。
      在这里插入图片描述

    3.主索引 vs. 辅助索引

    一个主文件仅可以有一个主索引,但可以有多个辅助索引
    主索引通常建立于主码/排序码上面;辅助索引建立于其他属性上面
    可以利用主索引重新组织主文件数据,但辅助索引不能改变主文件数据
    主索引是稀疏索引,辅助索引是稠密索引
    在这里插入图片描述

    4.聚簇索引和非聚簇索引

    聚簇索引—是指索引中邻近的记录在主文件中也是临近存储的;
    非聚簇索引—是指索引中邻近的记录在主文件中不一定是邻近存储的。

    • 如果主文件的某一排序字段不是主码,则该字段上每个记录取值便不唯一,此时该字段被称为聚簇字段; 聚簇索引通常是定义在聚簇字段上。
    • 聚簇索引通常是对聚簇字段上的每一个不同值有一个索引项(索引项的总数和主文件中聚簇字段上不同值的数目相同),索引字段即是聚簇字段的不同值,由于有相同聚簇字段值的记录可能存储于若干块中,则索引项的指针指向其中的第一个块。
    • 一个主文件只能有一个聚簇索引文件,但可以有多个非聚簇索引文件
    • 主索引通常是聚簇索引(但其索引项总数不一定和主文件中聚簇字段上不同值的数目相
      同,其和主文件存储块数目相同);辅助索引通常是非聚簇索引。
    • 主索引/聚簇索引是能够决定记录存储位置的索引;而非聚簇索引则只能用于查询,指出已存储记录的位置
      在这里插入图片描述

    5.倒排索引

    正排:一个文档包含了哪些词汇?

    • #Doc1, { Word1,Word2,… },哪些文档有这些关键词

    倒排:一个词汇包含在哪些文档中

    • Word1, { #Doc1, #Doc2, … ,关键词在哪些文档中
      在这里插入图片描述

    6.其他结构的索引

    多级索引:当索引项比较多时,可以对索引再建立索引,依此类推,形成
    多级索引

    • 常见的多级索引形式,如B树/B+树索引,以树型数据结构来组织索引项等

    多属性索引:索引字段由Table的多个属性值组合在一起形成的索引
    散列索引:使用散列技术组织的索引
    网格索引(Gridfile):使用多索引字段进行交叉联合定位与检索

    展开全文
  • 利用倒排索引和向量空间模型实现的信息检索系统。 完成工作: 带位置信息的倒排索引 转化空间模型 TOP K查询 BOOL查询 初步查询 拼写矫正 名词查询 拼写矫正(以下) 运行 环境要求:python3 在初次运行程序前请下载...
  • 主要为大家详细介绍了Mysql索引的类型和优缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 你有想过,如何用Hadoop实现【倒排索引】?

    千次阅读 多人点赞 2020-10-05 00:42:28
    这里引用一下维基百科上的定义: 倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。...

    写在前面: 博主是一名大数据的初学者,昵称来源于《爱丽丝梦游仙境》中的Alice和自己的昵称。作为一名互联网小白,写博客一方面是为了记录自己的学习历程,一方面是希望能够帮助到很多和自己一样处于起步阶段的萌新。由于水平有限,博客中难免会有一些错误,有纰漏之处恳请各位大佬不吝赐教!个人小站:http://alices.ibilibili.xyz/ , 博客主页:https://alice.blog.csdn.net/
    尽管当前水平可能不及各位大佬,但我还是希望自己能够做得更好,因为一天的生活就是一生的缩影。我希望在最美的年华,做最好的自己

            在正式开始之前,我们先来看看一个倒排索引的例子。
            
    在这里插入图片描述
            
            而具体什么是倒排索引?这里引用一下维基百科上的定义:

    倒排索引(英语:Inverted index),也常被称为反向索引置入档案反向档案,是一种索引方法,被用来存储全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。
    有两种不同的反向索引形式:

    • 一条记录的水平反向索引(或者反向档案索引)包含每个引用单词的文档的列表。
    • 一个单词的水平反向索引(或者完全反向索引)又包含每个单词在一个文档中的位置。

    后者的形式提供了更多的兼容性(比如短语搜索),但是需要更多的时间和空间来创建。

            倒排索引在搜索引擎中比较常见,百度,谷歌等大型互联网搜索引擎提供商均在搜索引擎业务中构建了倒序索引。本篇文章,就用一个简单的demo教大家如何使用Hadoop实现倒序索引。

    需求

            现在有3个文件,分别为 log_a.txt ,log_b.txt 和 log_c.txt,每个文件的内容如下所示:

    log_a.txt
    hello java
    hello hadoop
    hello java
    
    log_b.txt
    hello hadoop
    hello hadoop
    java hadoop
    
    log_c.txt
    hello hadoop
    hello java
    

            要求经过 Hadoop 的处理后,输出如下信息:

    hadoop  log_c.txt-->1 log_b.txt-->3 log_a.txt-->1
    hello   log_c.txt-->2 log_b.txt-->2 log_a.txt-->3
    java    log_c.txt-->1 log_b.txt-->1 log_a.txt-->2
    

    需求分析

            为了实现这种效果,我们可以很自然想到用MapReduce去处理。但是考虑到只用一个MapReduce处理,代码会写的比较冗长,可读性不强,对于新手小白不是很友好。于是本篇文章,作者介绍的就是如何通过两个MapReduce来实现“倒排索引”的功能!

            主要思路如下:

    倒排索引第一步的Mapper类
    我们输出如下结果:
    context.wirte(“hadoop->log_a.txt”, “1”)
    context.wirte(“hadoop->log_b.txt”, “1”)
    context.wirte(“hadoop->log_c.txt”, “1”)

    倒排索引第一步的Reducer
    最终输出结果为:
    hello --> log_a.txt 3
    hello --> log_b.txt 2
    hello --> log_c.txt 2

    倒排索引第二步的mapper
    hello --> log_a.txt 3
    hello–>log_b.txt 2
    hello–>log_c.txt 2

    倒排索引第二步的Reducer
    hello         log_c.txt–>2         log_b.txt–>2         log_a.txt–>3
    hadoop         log_c.txt–>1         log_b.txt–>3         log_a.txt–>1
    java         log_c.txt–>1         log_b.txt–>1         log_a.txt–>2

            好了,现在需求明确了,现在我们可以写代码了。

            这是倒排索引第一步的Mapper:InverseIndexStepOneMapper

    package io.alice;
    
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    import org.apache.hadoop.mapreduce.lib.input.FileSplit;
    
    import java.io.IOException;
    
    /**
     * @Author: Alice菌
     * @Date: 2020/10/4 20:38
     * @Description:
     * 读取文件的格式:
     * log_a.txt
     * hello java
     * hello hadoop
     * hello java
     *
     *  倒排索引第一步的Mapper类,
     *  输出结果如下:
     *  context.wirte("hadoop->log_a.txt", "1")
     *  context.wirte("hadoop->log_b.txt", "1")
     *  context.wirte("hadoop->log_c.txt", "1")
     */
    public class InverseIndexStepOneMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
    
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            if (value != null){
                // 获取一行的数据
                String line = value.toString();
                // 按照空格拆分每个单词
                String[] words = line.split(" ");
                if (words.length > 0){
                    // 获取数据的切片信息,并根据切片信息获取到文件的名称
                    FileSplit fileSplit = (FileSplit)context.getInputSplit();
                    String fileName = fileSplit.getPath().getName();
                    for (String word : words) {
                        context.write(new Text(word + "-->" + fileName),new LongWritable(1));
                    }
                }
            }
        }
    }
    

            倒排索引第一步的Reducer,InverseIndexStepOneReducer

    package io.alice;
    
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    import java.io.IOException;
    
    /**
     * @Author: Alice菌
     * @Date: 2020/10/4 20:47
     * @description: 完成倒排索引第一步的Reducer程序
     * 	    最终输出结果为:
     * 	 	hello-->log_a.txt	3
     * 		hello-->log_b.txt	2
     * 		hello-->log_c.txt	2
     * 		hadoop-->log_a.txt	1
     * 		hadoop-->log_b.txt	3
     * 		hadoop-->log_c.txt	1
     * 		java-->log_a.txt	2
     * 		java-->log_b.txt	1
     * 		java-->log_c.txt	1
     */
    public class InverseIndexStepOneReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
    
        @Override
        protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
            if (values != null){
                // 初始化一个变量 sum ,保存每个单词在每个文件中出现的次数
                long sum = 0;
                for (LongWritable value : values) {
                    sum += value.get();
                }
                context.write(key,new LongWritable(sum));
            }
        }
    }
    

            这是倒排索引第二步的Mapper:InverseIndexStepTwoMapper

    package io.alice;
    
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    import java.io.IOException;
    
    /**
     * @Author: Alice菌
     * @Date: 2020/10/4 21:03
     * @Description: 完成倒排索引第二步的mapper程序
     *
     * * 	    hello-->log_a.txt	3
     *  		hello-->log_b.txt	2
     *  		hello-->log_c.txt	2
     *  		hadoop-->log_a.txt	1
     *  		hadoop-->log_b.txt	3
     *  		hadoop-->log_c.txt	1
     *  		java-->log_a.txt	2
     *  		java-->log_b.txt	1
     *  		java-->log_c.txt	1
     *
     *  输出的信息为:
     * 	context.write("hadoop", "log_a.txt->1")
     *  context.write("hadoop", "log_b.txt->3")
     *  context.write("hadoop", "log_c.txt->1")
     *
     *  context.write("hello", "log_a.txt->3")
     *  context.write("hello", "log_b.txt->2")
     *  context.write("hello", "log_c.txt->2")
     *
     *  context.write("java", "log_a.txt->2")
     *  context.write("java", "log_b.txt->1")
     *  context.write("java", "log_c.txt->1")
     */
    public class InverseIndexStepTwoMapper extends Mapper<LongWritable, Text,Text,Text> {
    
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            if (value != null){
                String line = value.toString();
                // 将第一步的Reduce输出结果按照 \t 拆分
                String[] fields = line.split("\t");
                // 将拆分后的结果数组的第一个元素再按照 --> 分隔
                String[] wordAndFileName = fields[0].split("-->");
                // 获取到单词
                String word = wordAndFileName[0];
                // 获取到文件名
                String fileName = wordAndFileName[1];
                // 获取到单词数量
                long count = Long.parseLong(fields[1]);
                context.write(new Text(word),new Text(fileName + "-->" + count));
    
            }
        }
    }
    

            倒排索引第二步的Reducer,InverseIndexStepTwoReducer

    package io.alice;
    
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    import java.io.IOException;
    
    /**
     * @Author: Alice菌
     * @Date: 2020/10/4 21:21
     * @Description: 完成倒排索引第二步的Reducer程序
     * 得到的输入信息格式为:
     * <"hello", {"log_a.txt->3", "log_b.txt->2", "log_c.txt->2"}>
     * 	 * 最终输出结果如下:
     * 	 *  hello	log_c.txt-->2 log_b.txt-->2 log_a.txt-->3
     * 		hadoop	log_c.txt-->1 log_b.txt-->3 log_a.txt-->1
     * 		java	log_c.txt-->1 log_b.txt-->1 log_a.txt-->2
     */
    public class InverseIndexStepTwoReducer extends Reducer<Text,Text,Text,Text> {
        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            if (values != null){
                String result = "";
                for (Text value : values) {
                    result = result.concat(value.toString()).concat(" ");
                }
                context.write(key,new Text(result));
            }
    
        }
    }
    

            倒排索引的执行类:InverseIndexRunner

            这里需要格外的注意,因为我们平时接触到的MapReduce程度大多都是由一个Job完成的,本次案例在执行类中如何实现多个Job依次执行,大家可以借鉴学习!

    package io.alice;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.conf.Configured;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import org.apache.hadoop.util.Tool;
    import org.apache.hadoop.util.ToolRunner;
    
    import java.io.IOException;
    
    /**io.alice.InverseIndexRunner
     * @Author: Alice菌
     * @Date: 2020/10/4 21:39
     * @Description:  倒排索引的执行类
     */
    public class InverseIndexRunner extends Configured implements Tool {
    
        public static void main(String[] args) throws Exception {
    
            ToolRunner.run(new Configuration(),new InverseIndexRunner(),args);
    
        }
    
        public int run(String[] args) throws Exception {
    
    
            if (!runStepOneMapReduce(args)) {
                return 1;
            }
            return runStepTwoMapReduce(args) ? 0:1;
    
        }
    
        private static boolean runStepOneMapReduce(String[] args) throws Exception {
    
            Job job = getJob();
            job.setJarByClass(InverseIndexRunner.class);
    
            job.setMapperClass(InverseIndexStepOneMapper.class);
            job.setReducerClass(InverseIndexStepOneReducer.class);
    
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(LongWritable.class);
    
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(LongWritable.class);
    
            FileInputFormat.setInputPaths(job, new Path(args[0]));
            FileOutputFormat.setOutputPath(job, new Path(args[1]));
    
            return job.waitForCompletion(true);
    
        }
    
        private static boolean runStepTwoMapReduce(String []args) throws Exception {
    
            Job job = getJob();
            job.setJarByClass(InverseIndexRunner.class);
    
            job.setMapperClass(InverseIndexStepTwoMapper.class);
            job.setReducerClass(InverseIndexStepTwoReducer.class);
    
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(Text.class);
    
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(Text.class);
    
            FileInputFormat.setInputPaths(job,new Path(args[1] + "/part-r-00000"));
            FileOutputFormat.setOutputPath(job,new Path(args[2]));
            return job.waitForCompletion(true);
    
        }
    
        private static Job getJob() throws IOException {
            Configuration conf = new Configuration();
            return Job.getInstance(conf);
        }
    
    }
    

    测试执行

            我们将项目打成jar包上传至linux

    在这里插入图片描述
            然后将数据源所需要的文件上传至HDFS
    在这里插入图片描述
            然后执行命令:

            hadoop jar /home/hadoop/alice_data-1.0-SNAPSHOT.jar io.alice.InverseIndexRunner /data/input /data/oneoutput /data/twooutput

            程序就开始 奔跑 起来~
    在这里插入图片描述

            待到程序运行完毕,我们可以查看程序正确运行后的结果

    在这里插入图片描述
            看到最后的效果跟我们题目需求所想要的完全一致时,就说明我们的思路是没错滴~
            

    在这里插入图片描述

    小结

            我们每向他人学习到一项新的技能,一定要主动去思考别人解决问题的出发点,只有学会思考,才能举一反三,融会贯通!

            本篇文章就到这里,更多精彩文章及福利,敬请关注博主原创公众号【猿人菌】!

    扫码关注

    在这里插入图片描述

    关注即可获取高质量思维导图,互联网一线大厂面经,大数据珍藏精品书籍...期待您的关注!
    展开全文
  • 搜索引擎技术 —— 索引技术

    千次阅读 2021-12-09 20:31:41
    文章目录索引倒排索引单词词典动态索引索引的建立两遍文档遍历法归并法 索引 搜索引擎的索引其实是实现<关键词,文档>映射的具体的数据结构,其实现方式也是多种多样的:倒排索引、签名文件以及后缀树等等。...
  • WORD点击索引目录提示错误信息

    千次阅读 2014-08-29 09:10:18
    正常在WORD中打开超链接直接按Ctrl再单击超链接即可打开超链接,而Outlook和excel中,正常情况下直接单击超链接即可打开,但有时候打开所有Office中的超链接时却提示“由于本机的限制该操作,已被取消”;
  • 计算机二级培训-Word练习
  • 数字图书馆有一套基于 MySQL 的电子书管理系统,电子书的基本信息保存在数据库表中,书的数字内容以多种常见的文档格式(PDF、Word、PPT、RTF、TXT、CHM、EPUB等)保存在存储系统中。现在需要利用 ElasticSearch ...
  • 算法篇--倒排索引

    千次阅读 2021-08-01 17:28:39
    正向索引(forward index),反向索引(inverted index)更熟悉的名字是倒排索引。   在搜索引擎中每个文件都对应一个文件ID,文件内容被表示为一系列关键词的集合(实际上在搜索引擎索引库中,关键词也已经转换为...
  • Oracle建立二进制文件索引的方法
  • python字典索引

    千次阅读 2020-11-29 10:12:59
    字典的前几页,一般是索引,可以按照拼音来检索,也可以按照偏旁部首来检索。 索引的好处就是可以加快检索的速度,便于查找。 每一个索引会对应一个字。 ?那么python字典又是什么呢? 字典是 python 提供的一种常用...
  • 干货 | Elasticsearch 索引设计实战指南

    万次阅读 多人点赞 2020-02-03 22:46:02
    索引更新的时机是:当原始索引满足设置条件的三个中的一个的时候,就会更新为新的索引。为保证业务的全索引检索,一般采用别名机制。 在索引模板设计阶段,模板定义一个全局别名:用途是全局检索,如图所示的别名:...
  • mysql 中添加索引的三种方法

    千次阅读 2021-01-19 16:49:51
    在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法mysql 中添加索引的三种方法1.1 新建表中添加索引① 普通索引...
  • 本软件对指定的目录下的指定属性、指定扩展名文件(包括子目录下的文件)进行编目索引,保存为txt、htm、word文件(word文件需安装office)。 被勾选属性的文件可以索引,未勾选属性的文件将不被索引。既有勾选属性...
  • 录文件索引生成器1.5

    2016-01-07 22:30:40
    索引文件属性:无论选择多少,只要搜索到的文件某一属性符合即被选择,也就是属性之间是“或”的关系;选中“子目录”,表示搜索子目录下的文件。 被索引文件类型:各种类型之间是“或”的关系。比如,文档...
  • sql全文索引

    2014-04-23 09:52:35
    全文索引教程,初学者可以快速建立全文索引
  • Word中插入目录时未找到目录

    千次阅读 2013-12-23 09:50:13
    Word中插入目录时未找到目录
  • 索引文件属性:无论选择多少,只要搜索到的文件某一属性符合即被选择,也就是属性之间是“或”的关系;选中“子目录”,表示搜索子目录下的文件。 被索引文件类型:各种类型之间是“或”的关系。比如,选择...
  • 一文搞懂MySQL索引(清晰明了)

    万次阅读 多人点赞 2021-02-02 17:30:43
    索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 MySQL中常用的索引结构(索引底层的数据结构)有:B-TREE ,B+TREE ,...
  • 我们可以使用 Annoy 对 word2vec 向量建立索引并将其结果与 gensim 的 KeyedVectors索引进行对比( 像 Annoy 这样的局部敏感哈希使潜在语义索引成为现实): from gensim.models.keyedvectors import KeyedVectors ...
  • 1.正向索引 正向索引(正排索引):正排表是以文档的ID为关键字,表中记录文档中每个字的位置信息,查找时扫描表中每个文档中字的信息直到找出所有包含查询关键字的文档。 “文档1”的ID > 单词1:出现次数,出现...
  • python取索引

    千次阅读 2020-11-29 14:11:50
    数据的一些细微区别num = num1 = num # 输出:10 type:intnum2 = num# 输出: type:list总结: 分片包括起始索引对应的元素,但不包括终止索引对应的元素,索引为正值时可以发生越界但只会取到最后一个元素。...
  • 从零开始学习MySQL全文索引

    千次阅读 2021-01-19 08:25:50
    一、为什么要用全文索引我们在用一个东西前,得知道为什么要用它,使用全文索引无非有以下原因like查询太慢、json字段查询太慢(车太慢了)没时间引入ElasticSearch、Solr或者Sphinx这样的软件,或者根本就不会用(无法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,167
精华内容 18,866
关键字:

word索引项