美文网首页
面试被问到你做过搜索吗?该怎么回答

面试被问到你做过搜索吗?该怎么回答

作者: 提米锅锅 | 来源:发表于2019-09-28 21:05 被阅读0次

    估计很多人会秒回,做过啊,然后你自信满满的举了几个例子:
    可以用like关键字来模块匹配
    可以给字段建立索引提升速度

    你看面试官笑而不语,有点慌,马上补充了个,%放在最前不能匹配索引
    面试为微微一笑,那如果我要从大段文字中搜索,比如一段文章是:

    这个产品在日本每1.5秒就卖出一瓶,连续2年cosme大赏洗护类第一名!
    连续3年获得《美的 》《up》等日本美容杂志最优秀美发产品称号,更荣获日本药妆店无硅洗发水销量第一名!

    用户输,洗发水,匹配到这篇文章,这是个很常见的场景。
    或者我想搜,同时有“consme”和“洗发水”的文章。
    如果用sql匹配的话,那不是要把整段话都放进索引,还要like两次?

    可见sql只适用于简单的特定字段匹配,比如你有表结构
    产品名 | 分 类 | 买家
    product 洗发水 小丸子

    程序只用把户输入关键字去匹配这3个字段就可以。
    可如果把3个字段连成一个字段:product洗发水小丸子,这就回到了刚才的问题,
    因为sql是不识别语义的,它只能去模糊匹配,这样效率非常低。

    面对复杂搜索,比如一篇文章,需要的是Lucene这种全文搜索工具包来支持。

    Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。

    Lucene提供这样的功能:
    分词引擎:帮你把文章分成一个个单词,支持不同语言
    SDK:一套完成的工具包让你可以生成索引和查询

    刚才那段话用Lucene的中文分词器可以变成:
    日本,cosme,大赏,洗护类,第一名,美容杂,日本,药妆店,无硅,洗发水

    不同分词器侧重不一样,比如对于query这词,lucene自带的SmartChinese分词会分成queri。
    既然是全文检索,Luene查询方面自然提供了更丰富的匹配功能。

    短语搜索(Phrase Search):你可以指定日本,洗发水,还有一个距离作为参数,Lucene会返回同时存在这两次词,并且匹配文档中位置小于指定距离文档。

    范围搜索(Range Search)
    范围搜索匹配某个域上的值在一定范围的文档。例如,查询 “age:[18 TO 35]” 返回所有 age 域上的值在 18 到35 之间的文档。

    结果评分:比如同样两篇差不多长的文章,一篇奶粉出现了一次,另外一篇出现了10词,理论上后者和奶粉相关度更大,Lucene会给出更高的评分。

    Lucene简单的使用,使用之前需要建立索引,Lucene的索引就是一些自己格式的文件。
    每一个文章对应一个document,一般我们会把需要搜索的字段和用于标识的主键加到索引,可以结果里取出主键用于跳转等操作。

     public void genIndex(List<Product>productList,IndexWriter indexWriter){
            List<Document> docs = new ArrayList<Document>();
            for (Product p : productList) {
                Document doc = new Document();
                doc.add(new StringField("id", p.getId()+"", Field.Store.YES));
                doc.add(new TextField("name", p.getName(), Field.Store.YES));
                doc.add(new StringField("category", p.getCategory(), Field.Store.YES));
                // 保存price,
                float price = p.getPrice();
                // 建立倒排索引
                doc.add(new TextField("code", p.getCode(), Field.Store.YES));
                docs.add(doc);
            }
            try {
                // 清空索引
                indexWriter.deleteAll();
                indexWriter.addDocuments(docs);
                indexWriter.commit();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
    image.png

    一个简单的搜索代码

    IndexSearcher sh = searcherManager.acquire();
            TopDocs hits;
    
            //搜索code这个字段,完全匹配getter这个关键字,返回得分最高的前10条记录
             hits= sh.search(
                    new TermQuery(new Term("code","getter")
    
                    ),10);
    
    

    一个全文检索引擎还有很多功能,我们需要理解的是复杂的搜索在于语义的匹配,这点不是数据库的特长,需要搜索引擎来实现。

    关注提米锅锅的简书,后面我会分享一些Lucene的知识,帮你步入搜索的殿堂撒~~~

    相关文章

      网友评论

          本文标题:面试被问到你做过搜索吗?该怎么回答

          本文链接:https://www.haomeiwen.com/subject/pfxguctx.html