大数据互联网架构阶段 全文检索技术

全文检索

一、 全文检索的引出

  1. 我们生活中的数据总体分为两种:结构化数据 和非结构化数据 。
  2. 结构化数据: 指具有固定格式或有限长度的数据,如数据库,元数据等。
  3. 非结构化数据: 指不定长或无固定格式的数据,如邮件,word文档等。
    当然有的地方还会提到第三种,半结构化数据,如XML,HTML等,当根据需要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。
  4. 非结构化数据又一种叫法叫全文数据。
  5. 按照数据的分类,搜索也分为两种:
    1. 对结构化数据的搜索 :
      1. 如对数据库的搜索,用SQL语句。再如对元数据的搜索 (在2000年前, 大部分搜索都是使用优化数据库的索引 , 但是数据库的索引是有数据负载临界值的)
      2. 如利用windows搜索对文件名,类型,修改时间进行搜索等。
    2. 对非结构化数据的搜索 :如利用windows的搜索也可以搜索文件内容(文件检索是在内存中进行的 , 在window中对文件的最大加载限制为521M , 对于大量的文件 , 需要分批次读到内存中扫描后再释放 , 无法高效查询),Linux下的grep命令,再如用Google和百度可以搜索大量内容数据。
  6. 对非结构化数据也即对全文数据的搜索主要有两种方法:
    1. 顺序扫描法:所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢。如果你有一个80G硬盘,如果想在上面找到一个内容包含某字符串的文件,不花他几个小时,怕是做不到。Linux下的grep命令也是这一种方式。大家可能觉得这种方法比较原始,但对于小数据量的文件,这种方法还是最直接,最方便的。
    2. 全文检索:
      1. 但是对于大量的文件,这种顺序扫描就很慢了。
      2. 有人可能会说,对非结构化数据顺序扫描很慢,对结构化数据的搜索却相对较快(由于结构化数据有一定的结构可以采取一定的搜索算法加快速度),那么把我们的非结构化数据想办法弄得有一定结构不就行了吗?
      3. 这种想法很天然,却构成了全文检索的基本思路,也即将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
      4. 这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引 。
      5. 这种说法比较抽象,举几个例子就很容易明白,比如字典,字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有几种可以一一列举,于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。
      6. 这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search) 。
  7. 由此可以发现数据库检索方式的2个问题:
    1. 数据库无法存储海量数据
    2. 数据库中使用like查询 , 效率极低 , 数据库中索引容易被破坏

二、 倒排索引

  1. 全文索引的索引创建关键步骤是分词 。

    文章1:马蓉带着俩孩子快乐玩耍王宝强面容憔悴;
    文章2:王宝强另结新欢熊乃瑾却想念孩子; 
    分词第一步:
    文章1;(马蓉,文章1,出现次数1),(带着,1,1),(孩子,1,1),
    (王宝强,1,1);
    文章2;(王宝强,2,1),(新欢,2,1),(另结新欢,2,1),
    (熊乃瑾,2,1),(孩子,2,1);
    (疑难杂症,2,1)
    有重复出现在多个文章的词;索引要合并
     
    (马蓉,文章1,出现次数1),(带着,1,1),(孩子,[1,2],[1,2]),
    (王宝强,[1,2],[1,1]);(新欢,2,1),(结新欢,2,1),(熊乃瑾,2,1)
    
  2. 这个过程叫做倒排索引 , 在倒排索引中有两个重要的概念 :
    1. document: 被检索的内容
    2. 分词: 对文章进行分词 , 分词的意义是最小分词 , 不能再拆(在分词时 , 如果是对中文进行分词 , 可能出现分词结果比原文章还要大的情况) 。 在分词的结果中 , 记录了文章的位置 , 记录了关键字出现的次数等信息 。 分词后的索引文件 , 结构一致 , 可以进行压缩 。
  3. 在传统的索引中 , 是通过数据的记录查找某一个数值
  4. 在倒排索引中引入分词的概念 , 有分词直接定位到整个数据
  5. 倒排检索是全文检索的使用最多的一种索引计算方式

三 、Lucene

  1. 介绍: 搜索引擎的底层索引工具包 ,Lucene提供可以创建索引的api
  2. 创始人: Doug Cutting
  3. 使用Lucene创建索引之前需要了解数据库 、 java 、 Lucene中数据结构的对应关系
数据库 java lucene
varchar String StringField 或 TextField
bigInt Long LongField
int int IntField
tinyInt boolean BooleanField
。。。

4. lucene的使用
1. 导入Lucene的jar包
2. 编写代码

            /**
                 * 建立索引文件
                 * 步骤
                 * 1. 创建文件对象
                 * 2. 利用分词创建索引,  创建完索引可以利用分词查看器查看当前索引的分词内容
                 * @throws IOException 
                 * */
                @org.junit.Test
                public void createIndex() throws IOException {
                    Document doc = new Document();
                    //doc中的数据应该是调用代码将数据导入
                    //这里我们手动创建 数据 , 模拟读取数据库的过程
                    //创建 一个商品的数据索引 
                    doc.add(new LongField("id", 12324, Store.YES));//yes表示索引创建完成之后允许被使用。
                    doc.add(new TextField("title", "iphoneX  我就是最XXX的手机", Store.YES));
                    //title 和img 的数据其实都是String类型的 , 但是如果使用TextField则会对内容进行分词
                    //如果使用StringField , 则会将字段作为一个最小 分词处理
                    doc.add(new StringField("img", "http://www.baidu.com/hjdfh.jpg", Store.YES));
                    doc.add(new DoubleField("price", 299, Store.YES));
                    //利用分词创建索引
                    //创建索引文件保存目录
                    Directory dir = FSDirectory.open(new File("./index"));
                    //使用标准分词器分词
                    Analyzer analyzer = new StandardAnalyzer();
                    //调用索引config对象对写出的索引文件进行参数设定
                    //Version一定要与导入的jar包相对应 , 否则报错
                    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
                    //使用Lucene内置的流写出索引文件
                    IndexWriter writer = new IndexWriter(dir , config);
                    writer.addDocument(doc);
                    writer.close();
                    dir.close();

                }
3. 生成的索引为二进制文件 , 可以使用分词查看器查看![](https://i.imgur.com/o6SgILZ.jpg)![](https://i.imgur.com/bc8v0Va.jpg)![](https://i.imgur.com/RPE0cc1.png)
4. 观察分词结果 ,发现标准分词器 , 只能讲中文一个一个分割开 , 并不能将中文按照语义分割
5. 可以试用Luence中自带的中文分词器 , 修改代码![](https://i.imgur.com/PDR45fD.png)
6. 查看分词结果![](https://i.imgur.com/sSjMiYY.png)比用 标准分词器效果好一点 , 但是中文还是分的很烂
7. 引入第三方中文分词器(IKAnalyzer)修改代码![](https://i.imgur.com/JeuAD3k.png)查看分词结果![](https://i.imgur.com/OMehDDj.png) 可以看到具有语义的最小词被分了出来 。
8. 使用Lucene进行搜索

            /**
                 * 使用索引进行查询
                 * @throws IOException 
                 * */
                @org.junit.Test
                public void search() throws IOException {
                    //在索引中进行查询
                    Directory dir = FSDirectory.open(new File("./index2"));
                    IndexSearcher search = new IndexSearcher(IndexReader.open(dir));
                    Query query = new TermQuery(new Term("title" , "手"));//*代表检索所有的字段 , 可以检索单个字段如:tilte
                    TopDocs topDocs = search.search(query, 10);//第二个参数表示返回查询结果的条数
                    for(ScoreDoc sd : topDocs.scoreDocs) {
                        System.out.println("得分:"+sd.score);
                        Document doc = search.doc(sd.doc);
                        System.out.println(doc.get("id"));
                        System.out.println(doc.get("title"));
                        System.out.println(doc.get("img"));
                        System.out.println(doc.get("price"));
                    }
                    dir.close();
                }  
    ![](https://i.imgur.com/rSq12DR.png)

四、 Solr

  1. 是基于Lucene的搜索服务 ,是一套系统
  2. Solr具有自动化导入数据的功能
  3. 相当于把Lucene进行了包装 , 扩展了许多功能
  4. 安装Solr

    1. solr是基于java环境的 , 需要安装jdk – 略
    2. 获取solr资源 并解压
    3. 首次启动solr需要解压war包
      1. 进入solrbin目录
      2. 检查解压是否成功 访问${IP}:8983/solr
    4. 完成项目(京淘 简称jt)的其他配置

      1. 创建jt项目的 solr目录
      2. 其中jt项目的配置文件放在jt/conf下 , 数据文件(即索引文件)放在jt/data中

        1. 将配置文件放到conf中 使用rz -E命令上传文件

          1. schema.xml

            
            
                
                
            
                 
                
                
                
                
                
                
                
            
                id
            
                
                
                
                
                
                
                
            
                
                    
                
            
            
            
          2. solrconfig.xml

            
            
            
            
            
              
            
              
              4.10.2
            
              
            
              
            
              
              
            
              
              ${solr.data.dir:}
            
            
              
              
            
            
                      
                     
                ${solr.hdfs.home:}
                    
                ${solr.hdfs.confdir:}
                    
                ${solr.hdfs.blockcache.enabled:true}
                    
                ${solr.hdfs.blockcache.global:true}
            
               
            
              
              
            
              
              
            
              
              
                
                
                
            
                
                
            
                
                
            
                
                
                
            
                
                
            
                
                
            
                
                
            
                
                ${solr.lock.type:native}
            
                
                
            
                
                
            
                
                
            
                
                
                  
                  
                  
                  
                  
                  
                
            
                
                 true
            
                
                 false
              
            
            
              
              
              
              
              
              
            
              
              
            
                 
                
                  ${solr.ulog.dir:}
                
            
                
                  
                   ${solr.autoCommit.maxTime:15000} 
                   false 
                 
            
                
            
                  
                   ${solr.autoSoftCommit.maxTime:-1} 
                 
            
                
                
                
                
            
              
            
              
              
              
              
            
              
              
                
                1024
            
            
                
            
                
                
            
                
                
            
                
                
            
                 
                
            
                
                
            
                
                
            
            
                
                true
            
               
               
            
               
               20
            
               
               200
            
               
                
                
                  
                    
                  
                
                
                  
                    
                      static firstSearcher warming in solrconfig.xml
                    
                  
                
            
                
                false
            
                
                2
            
              
            
            
              
              
                 
                
            
                
                
                
                
                
                
              
            
              
              
            
            
              
                
                 
                   explicit
                   10
                   title
                 
                
                
                
                
                
                
                
                
            
              
              
                 
                   explicit
                   json
                   true
                   title
                 
              
            
            
              
              
                 
                   true
                   json
                   true
                 
              
            
              
            
              
                
                  {!xport}
                  xsort
                  false
                
            
                
                  query
                
              
            
            
            
            
            
            
              
              
                 
                   explicit
            
                   
                   velocity
                   browse
                   layout
                   Solritas
            
                   
                   edismax
                   
                      text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
                      title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0
                   
                   title
                   100%
                   *:*
                   10
                   *,score
            
                   
                     text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
                     title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0
                   
                   text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename
                   3
            
                   
                   on
                   true
                   cat
                   manu_exact
                   content_type
                   author_s
                   ipod
                   GB
                   1
                   cat,inStock
                   after
                   price
                   0
                   600
                   50
                   popularity
                   0
                   10
                   3
                   manufacturedate_dt
                   NOW/YEAR-10YEARS
                   NOW
                   +1YEAR
                   before
                   after
            
                   
                   on
                   content features title name
                   true
                   html
                   <b>
                   </b>
                   0
                   title
                   0
                   name
                   3
                   200
                   content
                   750
            
                   
                   on
                   false       
                   5
                   2
                   5       
                   true
                   true  
                   5
                   3           
                 
            
                 
                 
                   spellcheck
                 
              
            
            
              
              
                
                
              
            
              
            
              
              
                
                  true
                  ignored_
            
                  
                  true
                  links
                  ignored_
                
              
            
            
              
              
            
            
              
              
            
              
              
              
              
              
              
            
              
              
                
                  solrpingquery
                
                
                  all
                
                
                
              
            
              
              
                
                 explicit 
                 true
                
              
            
              
               
                
                
                
              
            
              
            
               
              
            
                text_general
            
                
            
                
                
                  default
                  text
                  solr.DirectSolrSpellChecker
                  
                  internal
                  
                  0.5
                  
                  2
                  
                  1
                  
                  5
                  
                  4
                  
                  0.01
                  
                
            
                
                
                  wordbreak
                  solr.WordBreakSolrSpellChecker      
                  name
                  true
                  true
                  10
                
            
                
                
            
                
                
            
                
                
              
            
              
              
                
                  title
                  
                  default
                  wordbreak
                  on
                  true       
                  10
                  5
                  5       
                  true
                  true  
                  10
                  5         
                
                
                  spellcheck
                
              
            
              
                
                  mySuggester
                  FuzzyLookupFactory      
                  DocumentDictionaryFactory      
                  cat
                  price
                  string
                
              
            
              
                
                  true
                  10
                
                
                  suggest
                
              
              
              
            
              
              
                
                  title
                  true
                
                
                  tvComponent
                
              
            
              
              
                
                  lingo
            
                  
                  org.carrot2.clustering.lingo.LingoClusteringAlgorithm
            
                  
                  clustering/carrot2
                
            
                
                
                  stc
                  org.carrot2.clustering.stc.STCClusteringAlgorithm
                
            
                
                
                  kmeans
                  org.carrot2.clustering.kmeans.BisectingKMeansClusteringAlgorithm
                
              
            
              
              
                
                  true
                  true
                  
                  name
                  
                  id
                  
                  features
                  
                  true
                  
                  
                  
                  false
            
                  
                  edismax
                  
                    text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
                  
                  *:*
                  10
                  *,score
                
                
                  clustering
                
              
            
              
              
            
              
              
                 
                  true
                  false
                     
                
                  terms
                
              
            
            
              
                
            
              
              
                
                  explicit
                  title
                
                
                  elevator
                
              
            
              
              
                
                  
                  
                  
                    
                      100
                    
                  
            
                  
                  
                    
                      
                      70
                      
                      0.5
                      
                      [-\w ,/\n\"']{20,200}
                    
                  
            
                  
                  
                    
                      ]]>
                      ]]>
                    
                  
            
                  
                  
            
                  
                  
            
                  
                  
            
                  
                  
            
                  
                  
                    
                  
            
                  
                  
                    
                      ,,
                           ,,
                           ,,
                           ,,
                           ,]]>
                      ]]>
                    
                  
            
                  
                    
                      10
                      .,!? 	
            
                    
                  
            
                  
                    
                      
                      WORD
                      
                      
                      en
                      US
                    
                  
                
              
            
               
              
              
            
              
                
            
              
              
            
              
              
              
            
              
                 
                text/plain; charset=UTF-8
              
            
              
                
            
            
              
              
                5
              
            
              
              
              
            
              
              
              
            
            
              
              
            
            
                
                  
                    dih-config.xml  
                  
                
            
            
              
              
                *:*
              
            
            
            
            
          3. dih-config.xml

             
                 
            
                 
                    
                     
                 
            
            
      3. schema文件解析
        1. 一个schema对应一个doc的所有索引结构,这里我们
        2. 定义一个xml对应商品的索引结构
        3. 红框内容是官方示例的基本结构,中间的是自定义拓展,最后几行是对类型的拓展,中文分词器;
      4. solrconfig文件解析
        1. 只需要放开最后的solr导入数据库的插件配置文件dih-confi.xml即可,所以这里将dih-config.xml也存进conf
      5. 将三个html文件存入conf目录下

        1. admin-extra.html

          http://www.apache.org/licenses/LICENSE-2.0
          
        2. admin-extra.menu-bottom.html

          http://www.apache.org/licenses/LICENSE-2.0
          
        3. admin-extra.menu-top.html

          http://www.apache.org/licenses/LICENSE-2.0
          
      6. 集成中文分词器

        1. 对中文分词时需要中文分词算法 ,所以需要引入中文分词器
        2. 将ik的jar包引入到solr的webapp中项目的lib中
        3. 将dist下的两个jar包复制进lib中个jar包

          #cp solr-dataimporthandler-* /home/software/solr-5.3.1/server/solr-webapp/webapp/WEB-INF/lib
          

      7. 将IKAnalyzer.cfg.xml 、 ext.dic 、 stopword.dic放到solr-5.2.1/server/solr-webapp/webapp/WEB-INF/classes (将自定义中文分词(如果使用默认可能未必最新,比如网络用语,专业名词都没有分词支持,需要自定义添加);有扩展字典,有停止字典(例如禁止网络用语骂人的话))

        1. IKAnalyzer.cfg.xml

          
            
            
              IK Analyzer 扩展配置
              
              ik_ext.dic; 
          
              
              ik_stopwords.dic; 
          
          
          
        2. ext.dic (扩展分词)

          电信3G手机
          双卡
          双待
          
        3. ik_stopwords.dic(停止分词)

          a
          an
          and
          are
          as
          at
          be
          but
          by
          for
          if
          in
          into
          is
          it
          no
          not
          of
          on
          or
          such
          that
          the
          their
          then
          there
          these
          they
          this
          to
          was
          will
          with
          
      8. 进入到solr的bin目录下 重启solr

        ./solr stop –all    #停止服务
        ./solr start        #启动服务       
        ./solr restart      #重启服务
        


6. 访问solr 创建core
7. 选择创建的核心工程
8. DIH数据导入添加完成之后 , 所有的数据库记录对应的doc索引就创建成功了
9. 测试

五 、 Solr引入电商项目

  1. 添加依赖

        
            org.apache.solr
            solr-solrj
            5.2.1        
        
        
            org.wltea.analyzer
            ik-analyzer
            5.3.0
        
    
  2. solr与spring整合 添加applicationContext-solrj.xml

        
    
            
                
                
                
                    
                
                
                
                
                
            
    
        
    
  3. 代码

        controller层
    
        @Controller
        public class SearchController {
            @Autowired
            private SearchService searchService;
            @RequestMapping("search")
            public String search(String q,Integer page,Model model) throws Exception{
                try{
                    q=new String(q.getBytes("ISO8859-1"),"UTF-8");
                }catch(Exception e ){
                    e.printStackTrace();
                }
                //准备一个分页数量rows
                Integer rows=20;
                List itemList=searchService.queryItemList(q,page,rows);
                model.addAttribute("itemList", itemList);
                return "search";
            }
        }
    
    service层
    @Service
    public class SearchService {
    
        @Autowired
        private HttpSolrClient client;
        public List queryItemList(String q,Integer page,Integer rows) throws Exception{
            if(null==page){
                page=1;}
            //起始位置
            Integer start=Math.max(page, 1);
            SolrQuery query= new SolrQuery();
            query.setQuery("title:"+q);//"title:三星"
            query.setStart(start);
            query.setRows(rows);
            //执行连接获取数据
            QueryResponse response=client.query(query);
            List itemList=response.getBeans(Item.class);
            return itemList;
        }
    

你可能感兴趣的:(WEB,大数据)