对lunr.js的希腊语言支持



在lunr中为希腊单词注册一个新的stemmer函数没有按预期工作。这是我在codepen上的代码。我没有收到任何错误,功能stemWord()单独使用时工作良好,但它无法阻止lunr中的单词。下面是代码示例:

function stemWord(w) {
// code that returns the stemmed word
};
// create the new function
greekStemmer = function (token) {
    return stemWord(token);
};
// register it with lunr.Pipeline, this allows you to still serialise the index
lunr.Pipeline.registerFunction(greekStemmer, 'greekStemmer')
  var index = lunr(function () {
    this.field('title', {boost: 10})
    this.field('body')
    this.ref('id')
    this.pipeline.remove(lunr.trimmer) // it doesn't work well with non-latin characters
    this.pipeline.add(greekStemmer)
  })
    index.add({
    id: 1,
    title: 'ΚΑΠΟΙΟΣ',
    body: 'Foo foo foo!'
  })
  index.add({
    id: 2,
    title: 'ΚΑΠΟΙΕΣ',
    body: 'Bar bar bar!'
  })

  index.add({
    id: 3,
    title: 'ΤΙΠΟΤΑ',
    body: 'Bar bar bar!'
  })

在lunr中,词干是作为管道函数实现的。在索引文档时对文档中的每个单词执行管道函数,在搜索时对搜索查询中的每个单词执行管道函数。

对于一个在管道中工作的函数,它必须实现一个非常简单的接口。它需要接受单个字符串作为输入,并且必须以字符串作为输出进行响应。

所以一个非常简单(而且没用)的管道函数应该是这样的:

var simplePipelineFunction = function (word) {
  return word
}
要真正使用这个管道函数,我们需要做两件事:

  1. 将其注册为管道函数,这允许lunr正确地序列化和反序列化你的管道。
  2. 将其添加到您的索引管道中。

看起来像这样:

// registering our pipeline function with the name 'simplePipelineFunction'
lunr.Pipeline.registerFunction(simplePipelineFunction, 'simplePipelineFunction')
var idx = lunr(function () {
  // adding the pipeline function to our indexes pipeline
  // when defining the pipeline
  this.pipeline.add(simplePipelineFunction)
})

现在,您可以使用上面的代码,并替换出管道函数的实现。因此,它可以使用您找到的希腊词干来词干,而不是仅仅返回原封不动的单词,可能像这样:

var myGreekStemmer = function (word) {
  // I don't know how to use the greek stemmer, but I think
  // its safe to assume it won't be that different than this
  return greekStem(word)
}

使lunr适应英语以外的语言需要的不仅仅是添加你的词干。lunr的默认语言是英语,因此,默认情况下,它包含专门用于英语的管道函数。英语和希腊语的差异很大,您可能会遇到用英语默认值索引希腊语单词的问题,因此我们需要做以下操作:

  1. 将默认的词干替换为特定于语言的词干
  2. 删除默认的修剪器,它不能很好地处理非拉丁字符
  3. 替换/删除默认的停止词过滤器,它不太可能在英语以外的语言中使用。

修剪器和停止词过滤器是作为管道函数实现的,因此对词干器实现特定于语言的函数是类似的。

那么,要为希腊语设置lunr,你需要这样做:

var idx = lunr(function () {
  this.pipeline.after(lunr.stemmer, greekStemmer)
  this.pipeline.remove(lunr.stemmer)
  this.pipeline.after(lunr.trimmer, greekTrimmer)
  this.pipeline.remove(lunr.trimmer)
  this.pipeline.after(lunr.stopWordFilter, greekStopWordFilter)
  this.pipeline.remove(lunr.stopWordFilter)
  // define the index as normal
  this.ref('id')
  this.field('title')
  this.field('body')
})

要获得更多的灵感,你可以看看优秀的lunr-languages项目,它有许多为lunr创建语言扩展的例子。你甚至可以提交一篇希腊文!

EDIT看起来我不知道lunr.Pipeline API以及我想的,没有replace函数,而是我们只是在函数后插入替换,然后删除它。

EDIT添加此内容以帮助将来的其他人…事实证明,问题在于lunr中令牌的大小写。Lunr希望将所有标记都视为小写,这是在标记器中完成的,没有任何可配置性。对于大多数语言处理函数来说,这不是问题,实际上,大多数假设单词是小写的。在这种情况下,由于希腊语词干的复杂性,希腊词干只能词干大写单词(我不是希腊语的演讲者,所以不能评论词干有多复杂)。一个解决方案是在调用希腊词干之前转换为大写,然后在将标记传递给管道的其余部分之前转换回小写。

相关内容

  • 没有找到相关文章

最新更新