2020-03-10 数学公式结构化与搜索预研

1. 数学公式结构化与显示

1.1 主流的数学公式处理:

  • laTex:排版与印刷描述语言。可以用于公式描述,也可以用于公式的结构化存储。已经成为行业标准。
  • AsciiMath:一种数学markup语言,用于公式描述,可以用 MathJax 来渲染。对公式描述的能力和laTex接近,但并未成为行业标准。
  • mathml:html5支持的数学公式渲染语言,小程序是否直接支持,需要进一步研究。该语言适用于在web页面上渲染公式,但不适合用于结构化存储。
  • mathtype:和word集成的公式编辑器,无法独立使用。
  • js的laTex渲染工具:MathJax 和 LaTeXMathML
  • 目前已经有js库用于laTex向mathml转换。这样可以使用laTex来结构化描述题目,然后在渲染时动态转换为mathml。

1.2 小程序中如何使用

  • 小程序的latex实现:https://blog.csdn.net/sbfkcel/article/details/103979456
  • 还有种实现思路是后台返回svg。
  • 最差的是用webview调js,但那个效率肯定很低。

2. 题库搜索

2.1 基于题号的搜索

显然,当有题号时,直接根据题号搜索是最快的。
如果题目来自我们自己的题库,那么可以在题目上提供我们自己的题号。扫描答案时,如果能识别到这个题号,那么根据题号直接进行数据库搜索,直接得到答案。这是最简单的场景。
这个场景的缺陷,在于该场景很少见。大多数情况下,我们都没有题号。或者答题纸上的题号,和系统中的题号,并不对应。

2.2 基于题目的搜索

大多数情况下,扫描答题纸时,题号不一定能和题目精确对应起来,需要根据扫描到的题目文本,在题库中搜索到对应的题目,再根据题目和答案的关联,找到标准答案。
因此题目搜索可以从两个方面入手:

    1. 根据题目内容进行文本匹配;
  • 由于文本匹配的精确度问题,很难高精度匹配一个题目,而是得到一个匹配度从高到底排序的匹配结果列表。
  • 目前通行的中文匹配原理,是通过分词器对题目文本进行短语分词,然后将分出的短语,在题库中进行匹配
    1. 根据题目中公式,进行匹配。
  • 题库搜索和一般的文本搜索相比,有自身的特点:比如,数学题目中往往有关键公式。而公式往往以 laTex 等语言描述,且是一个整体不允许拆分。
  • 可以在文本匹配结果的基础上,对特殊的公式进行精确匹配,往往可以找到唯一的匹配结果。

根据我们项目的特点,我个人建议直接采用 Lucene,或集成 Solr。

2.3 可参考的文本搜索工具

目前开源可用的搜索工具,主要分为 Lucene 系和其他。
Lucene系:主流的Java全文搜索工具,都是基于 Lucene 实现,只是在 Lucene 搜索引擎基础上提供易用性封装、分布式能力封装,或提供丰富的查询接口。各产品大致都另外提供了一些特色功能。但其基本搜索功能仍然是使用Lucene实现的能力和框架;在搜索这个关键点上,并未提供超出 Lucene 的新能力。
其他系,一方面说明其不是目前的主流,另外一方面说明其提供了独特于 Lucene 的引擎核心。

2.3.1 Lucene 系搜索引擎工具。

  • Lucene:最成熟的Java全文搜索框架

这个是最成熟应用最广的Java分词框架。几乎已经成为Java全文本搜索的规范了。几乎所有的主流Java搜索服务器,都直接或间接基于 Lucene 构建。
优点:

  • 技术非常成熟,事实上的行业标准。
  • 可完全根据自身业务制定搜索逻辑和索引策略组合。
  • 只是搜索引擎框架,可以和应用集成,或发布为自己的微服务。
    缺点:
  • 其优点就是其缺点。它只是一个全文搜索框架,不是一个开箱即用的产品。
  • 完全定制,也就意味着需要自行维护集成切词、索引、搜索服务实现等一系列的功能。
  • 不提供分布式能力,由集成的应用提供。
  • ElasticSearch:基于Lucene的分布式搜索引擎

它是基于Lucene构建的分布式搜索引擎产品,开箱即用。通过http接口进行查询。Github目前使用的就是 ES。
优点:

  • 它是基于Lucene构建的分布式搜索引擎产品,因此拥有Lucene的强大功能和成熟度。
  • 开箱即用,独立部署,通过集群支持水平扩展和灾备。无需自行维护索引、存储、切词等。
  • 提供restful 接口,使用简单。
  • 集成简单。有现成的客户端spring集成方案。
  • 实时搜索(同时创建索引并搜索)和非实时搜索查询速度相差不大,比较稳定。
  • 当数据量变得非常大时,扩展容易,搜索性能稳定。
    缺点:
  • 独立部署的服务器,对资源要求高。在前期需求量不大时,对资源浪费严重。
  • 完善的分布式部署能力,且操作相对简单。
  • 允许根据自身业务需要定制索引优化,但想要基于题库特点进行索引优化有一定复杂度。
  • 这是商业公司维护的开源产品,如果存在问题,可能响应会慢。
  • Solr: Lucene 维护团队自己维护的基于Lucene的搜索服务器

它实际上就是 Lucene 团队维护的分布式搜索服务器产品。
优点:

  • 开箱即用,独立部署的产品。在这一点上,和 ES 没有差别。当数量上去以后,可以通过集群水平扩展。
  • 实际上就由 Lucene 团队维护,有很大的开源维护者群体。
  • 一般数据量下的索引查询,速度比 ES 快2倍。
    缺点:
  • 独立部署的服务器,对资源要求高。在前期需求量不大时,对资源浪费严重。
  • 有完善的分布式支持;相对 ES 来说,其分布式部署复杂度更高。
  • 允许根据自身业务需要定制索引优化,但想要基于题库特点进行索引优化有一定复杂度。
  • 不适合实时搜索。创建索引同时进行搜索,性能只有 ES 的1/4。但对我们的场景来说,这个问题似乎影响不大。
  • 数据量非常大时,性能下降很快。但这个非常大,对我们的应用场景来说,似乎不存在。
  • Solandra:基于Solr 和 nosql 数据库 cassandra 构建的分布式搜索服务器。

它和 Solr 的主要差别,就在于重构了 Solr 的索引层,将数据存储 nosql 数据库 cassandra。Solr的缺点,它都有,且索引维护不可见。对我们来说,这个东西没有什么用。

  • Nutch:基于 Lucene 的开源Java 实现的搜索引擎。

它是一个独立的搜索引擎产品,基于 Lucene 的倒排表索引结构。
优点:

  • 完整的搜索引擎产品,开箱即用。
  • 提供了爬虫实现,可以根据配置主动爬取数据。(但这一点对我们的场景无用)
    缺点:
  • 独立部署的服务器,对资源要求高。在前期需求量不大时,对资源浪费严重。
  • 很难根据自身业务特定自定义索引逻辑。
  • Compass: 基于 Lucene 的介于搜索引擎和持久层之间的搜索引擎框架

它不是一个独立产品,更像是对 Lucene 封装提供和持久层结合能力的框架。
优点:

  • 直接封装 Lucene,拥有Lucene的成熟度。
  • 提供了和持久层结合的能力。可以直接将搜索模型和业务模型映射起来,并在维护业务数据时直接同步维护索引数据等。
  • 有提供spring集成工具。
    缺点:
  • 优点就是缺点,它封装了 Lucene,引入了新的复杂度。需要了解其封装框架,包括索引配置、对象映射等。
  • 优点就是缺点,和持久层、模型层结合,对我们这种只是题目搜索才需要使用全文搜索的项目来说,有点过度耦合了。

2.3.2 其他系搜索引擎

  • IndexTank:Linkin开源的实时搜索引擎。底层采用了Lucene的倒排索引,除此以外,有自己的一整套索引和搜索机制。

优点:

  • 实时搜索引擎。一遍构建索引一遍进行搜索的情况下,性能也很好。但对我们的场景来说,似乎不必要。
  • 针对Linkin自身的需求,它将数据分为三大类:倒排表数据、动态数据、原始文档数据。倒排表数据部分的原来来自Lucene;它特有的“动态数据”部分可以提供和索引相关的其他信息的维护,但对我们的场景来说无用。
    缺点:
  • Linkin维护的开源产品,但实际上开源提交者并不多,不是主流。
  • 它的定位,介于搜索引擎框架和产品之间,不能开箱即用。要使用,还是需要自行开发。
  • 非主流框架,8年不更新了,遇到问题也比较难找到资料。几乎可以认为是Linkin自己的玩具。

你可能感兴趣的:(2020-03-10 数学公式结构化与搜索预研)