【问题标题】:How to search for closest tag set match in JavaScript?如何在 JavaScript 中搜索最接近的标签集匹配?
【发布时间】:2017-10-07 11:17:00
【问题描述】:

我有一组文档,每个文档都带有一组标签,其中可能包含空格。用户提供了一组可能拼错的标签,我想找到匹配标签数量最多的文档(可选加权)。

有数千个文档和标签,但每个文档最多有 100 个标签。

我正在寻找一种轻量级且高性能的解决方案,其中搜索应该完全在客户端使用 JavaScript,但可以使用 node.js 对索引进行一些预处理。

我的想法是使用 multiset 为文档创建标签的反向索引,以及找到拼写错误标签的正确拼写的模糊索引,这些索引在 node.js 的预处理步骤中创建并序列化为 JSON 文件.在搜索步骤中,我想先查询查询集的每个项目的模糊索引以获得最可能正确的标签,如果存在则查询反向索引并将结果集添加到包中(编号集) .对所有输入标签执行此操作后,按降序排序的袋子内容应该提供最佳匹配文档。

我的问题

  1. 这似乎是一个常见问题,是否已经有一个我可以重复使用的实现?我查看了 lunr.js 和 fuse.js,但它们似乎有不同的关注点。
    1. 这是解决问题的明智方法吗?您是否看到任何明显的改进?
    2. 将模糊步骤与倒排索引分开是更好还是有办法将它们结合起来?

【问题讨论】:

    标签: javascript search tagging fuzzy-search


    【解决方案1】:

    你应该能够使用 Lunr 实现你想要的,这是一个简化的例子(和一个jsfiddle):

    var documents = [{
      id: 1, tags: ["foo", "bar"],
     },{
      id: 2, tags: ["hurp", "durp"]
    }]
    
    var idx = lunr(function (builder) {
      builder.ref('id')
      builder.field('tags')
    
      documents.forEach(function (doc) {
        builder.add(doc)
      })
    })
    
    console.log(idx.search("fob~1"))
    console.log(idx.search("hurd~2"))
    

    这利用了 Lunr 中的几个功能:

    1. 如果文档字段是一个数组,那么 Lunr 假定元素已经被标记,这将允许您按原样索引包含空格的标签,即“foo bar”将被视为单个标签(如果这是你想要什么,问题中并不清楚)
    2. 支持模糊搜索,这里使用查询字符串格式。波浪号后面的数字是最大编辑距离,还有更多documentation 详细说明。

    结果会按照与查询最匹配的文档进行排序,简单来说,匹配标签越多的文档排名越高。

    将模糊步骤与倒排索引分开更好还是有办法将它们结合起来?

    一如既往,视情况而定。 Lunr 维护两个数据结构,一个倒排索引一个图。该图用于进行通配符和模糊匹配。它保留单独的数据结构,以便于在倒排索引中存储与匹配无关的术语的额外信息。

    根据您的用例,可以将两者结合起来,一个有趣的方法是有限状态转换器,只要您要存储的数据很简单,例如一个整数(想想文档 ID)。有一篇很好的文章讨论了这种数据结构,它类似于 Lunr 中使用的数据结构 - http://blog.burntsushi.net/transducers/

    【讨论】:

      猜你喜欢
      • 2010-10-01
      • 2014-03-24
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多