c# - Lucene:查找最接近的数字

标签 c# lucene lucene.net

我正在使用Lucene.Net版本3.0.3.0并尝试找到一种方法来搜索数字(整数)并最终返回结果最接近的数字在列表中得分较高。

为了简单起见,我简化了文档:

private void WriteDocument(IndexWriter writer, string product, int weight)
{
    Document document = new Document();

    var fieldProduct = new Field("Product", product, Field.Store.YES, Field.Index.NOT_ANALYZED);
    document.Add(fieldProduct);

    var fieldWeight = new NumericField("Weight", Field.Store.YES, true);
    fieldWeight.SetIntValue(weight);
    document.Add(fieldWeight);

    writer.AddDocument(document);
}

它由 2 个字段组成:产品重量。最后一个是数字字段。

出于测试目的,我插入了一堆文档:

WriteDocument(writer, "ONORNN", 100);
WriteDocument(writer, "ONORNN", 200);
WriteDocument(writer, "ONORNN", 300);
WriteDocument(writer, "ONORAA", 400);

前 3 个具有相同的产品代码。权重可以是 1 到 999 之间的任何值。

我可以看到 Lucene.Net 提供了一种使用 NumericRangeQuery 搜索某个范围内的数字的方法,但这对我没有帮助,因为它不允许输入接近值,只有 mixmax:

var weightRange = NumericRangeQuery.NewIntRange("Weight", 1, 999, true, true);

我可以使用任何其他类型的查询来实现我正在寻找的结果吗?

最佳答案

不幸的是,我不是 C# 专家,所以我快速浏览了 Lucene.Net 3.0.3 中可用的内容,这里是建议的解决方案(我将混合 Java 代码,但希望你能理解它)

所以,您需要使用 FunctionQuery它实际上不是 Lucene 3.0.3 的一部分,但它是为 Lucene.Net 移植的。此查询将允许根据文档字段中的值提供自定义评分。

Query q = new FunctionQuery(new DistanceDualFloatFunction(new IntFieldSource("weight"), new ConstValueSource(245)));

static class DistanceDualFloatFunction extends DualFloatFunction {

    public DistanceDualFloatFunction(ValueSource a, ValueSource b) {
      super(a, b);
    }

    @Override
    protected String name() {
      return "distance function";
    }

    @Override
    protected float func(int doc, FunctionValues aVals, FunctionValues bVals) {
      return 1000 - Math.abs(aVals.intVal(doc) - bVals.intVal(doc));
    }
  }

所以,基本上我正在创建一个函数查询,它使用两个参数函数并精确计算 245 (我选择的值)和实际值之间的绝对差。

我有以下文件:

addDocument(writer, "doc1", 100);
addDocument(writer, "doc2", 200);
addDocument(writer, "doc3", 300);
addDocument(writer, "doc4", 400);
addDocument(writer, "doc5", 500);
addDocument(writer, "doc6", 600);

结果如下:

stored,indexed,tokenized<title:doc2> 955.0
stored,indexed,tokenized<title:doc3> 945.0
stored,indexed,tokenized<title:doc1> 855.0
stored,indexed,tokenized<title:doc4> 845.0
stored,indexed,tokenized<title:doc5> 745.0
stored,indexed,tokenized<title:doc6> 645.0

您将面临的问题:

  • Lucene.Net 没有 DualFloatFunction,因此您需要以某种方式使用您拥有的 already 。对我来说最有希望的是 ReciprocalFloatFunction 。另一种方法是实现您自己的 DualFloatFunction。

总体结论 - 这是可能的,但您需要花一些时间将其采用到 C# 和 Lucene.Net。

解决方案的完整源代码位于 here .

关于c# - Lucene:查找最接近的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45773559/

相关文章:

c# - 将 Lucene 索引文件存储到远程位置

search - Elasticsearch完成建议者字段包含逗号分隔的值

c# - ASP .NET CORE 找不到包含自定义程序集的文件或程序集

c# - 父任务不等待子任务

c# - .exe 窗口中的鼠标模拟

lucene - 如何使用原生 Lucene 查询语法?

filter - 如何在 Lucene.net 中使用 multifieldquery 和过滤器

c# - C# 和 JavaScript 之间的 pbkdf2 计算不一致

solr - 如何使用solr中的信息增益来计算术语分数?

apache - 集成 Solr 和 Mahout