天天看点

elasticlunr.js 最新版本v0.6.7发布啦应用示例为什么你需要elasticlunr.js?

本小编写的第一个有点实用价值的开源类库elasticlunr.js刚刚发布了最新的版本v0.6.7, 该项目是在lunr.js的基础上进行大幅度改进生成的。希望各位帮忙做code review,本人并不熟悉javascript, 还有,如果方便的话希望给位帮忙在github上点赞,嘿嘿,您的一个赞,是我继续努力改进该项目的最大动力来源。

本项目的主页:elasticlunr.js

项目代码:elasticlunr.js code

项目文档: elasticlunr.js doc

项目的npm发布地址: elasticlunr.js npm

项目在线演示地址: elasticlunr.js demo

目前,与lunr相比,比较大的改动主要有:

1. Query-Time Boosting, 目前elasticlunr支持查询时的权重调整,可以方便的根据不同的应用场景调整不同field的权重,不用在建立索引的时候直接写入不可以调整的field weight.

2. More Rational Scoring Mechanism, 目前elasticlunr.js采用和elasticsearch 以及 lucence完全一直的文档评分准则,比lunr.js的评分更加准确、客观。目前采用的评分准则在通用的

tf

idf

tf*idf

还做了field length normalization, field length normalization 有点像BM25模型,如果一个field太长,会导致tf比较大,做了field length normalization以后能够对长field的tf做一个penality;同时,elasticlunr.js还做了coord normalization 和 query normalization, 将query-time boosting 信息enroll 到了query normalization中。关于Elasticlurn和elasticsearch是如何具体的做scoring的,请参考我的文章Elasticsearch scoring detailed explanation.

3. Field-Search, 用户建立索引的时候,可以指定文档的哪些field需要建立到索引中,同时,用户在查询的时候可以指定要查找哪些field, 可以指定给每个field 多少权重,这样能够实现非常灵活的查询。

4. Boolean Model, 用户查询的时候可以指定全局的boolean model, 也可以指定某个field的boolean model, field boolean model 会覆盖全局的boolean model, 这样用户就可以指定是否需要在某个field中包含全部的query tokens.

5. Combined Boolean Model, TF/IDF Model and the Vector Space Model, 目前elasticlunr整合了boolean model, tf/idf model 和 vector space model 进行文档ranking分数的计算,这个计算使得文档的ranking准确性更好。文档分数计算请见:Elasticsearch scoring detailed explanation. 未来还会包括其他的ranking model, 例如BM25 Model.

6. Fast, elasticlunr.js在计算文档相似度的时候不用计算query 的向量和文档的向量,没有采用vector space model, 而是采用计算每个query token在出现文档中的score, 然后把每个query token的score累加起来,最后进行query normalization, 所以在进行query的时候计算速度比较快。

7. Small Index Size, elasticlunr.js没有存储token corpus, 因为没有必要计算文档向量,这样可以节省一部分存储大小;同时,elasticlunr.js用户可以设置是否存储json格式的文档,如果用户比较关心index的大小,可以设置为不存储json格式的documents;最重要的部分是,elasticlunr.js 优化了index的存储信息,使得index的大小可以降低到原来的一般左右。

应用示例

建立索引

如果用户不设置是否存储文档,默认为存储,这样用户可以用JSON文档生成摘要:

var index = elasticlunr(function () {
    this.addField('title');
    this.addField('body');
    this.setRef('id');
});
           

用户可以设置不存储JSON文档:

var index = elasticlunr();
index.addField('title');
index.addField('body');
index.setRef('id');
index.saveDocument(false);
           

索引文档

Adding documents to the index is as simple as:

直接可以索引JSON格式的文档

var doc1 = {
    "id": ,
    "title": "Oracle released its latest database Oracle 12g",
    "body": "Yestaday Oracle has released its new database Oracle 12g, this would make more money for this company and lead to a nice profit report of annual year."
}

var doc2 = {
    "id": ,
    "title": "Oracle released its profit report of 2015",
    "body": "As expected, Oracle released its profit report of 2015, during the good sales of database and hardware, Oracle's profit of 2015 reached 12.5 Billion."
}

index.addDoc(doc1);
index.addDoc(doc2);
           

简单文档检索

index.search("Oracle database profit");
           

检索结果:

[{
    "ref": ,
    "score": 
},
{
    "ref": ,
    "score": 
}]
           

因为elasticlunr.js已经有非常复杂的、合理的评分系统,所以大部分情况下用户只需要使用最简单的查询就可以满足需要,当然如果用户比较熟悉检索原理的话,也可通过配置实现更加复杂的、针对不同应用情况的检索。

field search && configuration

用户可以指定查询哪些field, 给每个field多少权重,在每个field中使用哪个boolean model进行检索。

index.search("Oracle database profit", {
    fields: {
        title: {boost: },
        body: {boost: }
    },
    bool: "OR"
});
           

上面的查询例子通过设定全局的bool model表示在每个field中,都采用这个bool model, 如果在某个field中指定了其他的bool model,那么field的bool model 会覆盖全局的bool model, 例如:

index.search("Oracle database profit", {
    fields: {
        title: {boost: , bool: "AND"},
        body: {boost: }
    },
    bool: "OR"
});
           

为什么你需要elasticlunr.js?

  1. 在很多情况下,你可能想让自己的一些文档能够实现检索的功能,但是又不想提供太复杂服务器环境配置,这时候你可以完全用elasticlunr.js建立文档索引,然后在浏览器中使用搜索功能,你只需要在服务器上提供简单的apache静态网页服务即可。
  2. 很多时候用户可能在受限的网络环境下,不能总是访问网络或者访问网络的成本比较大,例如移动设备,这个时候如果能共提供离线的文档并支持搜索功能,对于用户来说是非常友好的。例如,某个模块的文档,用户往往在下载模块的时候就已经包含文档了,如果用户在本地使用这些文档的话,提供搜索功能是非常有用的。

继续阅读