C# Lucene:找到最近的号码

C# Lucene:找到最近的号码,c#,lucene,lucene.net,C#,Lucene,Lucene.net,我正在使用Lucene.Netver3.0.3.0并试图找到一种方法来搜索一个数字(整数),最终返回最接近的数字在列表中得分较高的结果 为了简单起见,我简化了文档: private void WriteDocument(IndexWriter writer, string product, int weight) { Document document = new Document(); var fieldProduct = new Field("Product", produ

我正在使用Lucene.Netver3.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);
}
它由两个字段组成:产品重量。最后一个是数字字段

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

WriteDocument(writer, "ONORNN", 100);
WriteDocument(writer, "ONORNN", 200);
WriteDocument(writer, "ONORNN", 300);
WriteDocument(writer, "ONORAA", 400);
addDocument(writer, "doc1", 100);
addDocument(writer, "doc2", 200);
addDocument(writer, "doc3", 300);
addDocument(writer, "doc4", 400);
addDocument(writer, "doc5", 500);
addDocument(writer, "doc6", 600);
前3个具有相同的产品代码。权重可以是介于1和999之间的任何值

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

var weightRange = NumericRangeQuery.NewIntRange("Weight", 1, 999, true, true);
有没有其他类型的查询可以用来实现我想要的功能?

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

所以,您需要使用它,它实际上不是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(我选择的值)和实际值之间的绝对差值

我有以下文件:

WriteDocument(writer, "ONORNN", 100);
WriteDocument(writer, "ONORNN", 200);
WriteDocument(writer, "ONORNN", 300);
WriteDocument(writer, "ONORAA", 400);
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
存储、索引、标记化955.0
存储、索引、标记945.0
存储、索引、标记化855.0
存储、索引、标记化845.0
存储、索引、标记745.0
存储、索引、标记645.0
你将要面对的问题:

  • 没有
    DualFloatFunction
    是Lucene.Net,因此您需要以某种方式使用现有功能。对我来说最有希望的是。另一种方法是实现自己的双浮点函数
总体结论-这是可能的,但您需要花一些时间将其应用到C#和Lucene.Net


解决方案的完整来源已找到。

太好了。非常感谢你。明天我会试一试,然后带着一些反馈回来。干杯,不客气。不幸的是,对你来说,这仍然是一些事情要做,尽管看起来是可行的。非常感谢,很有效。我从不同的来源借用了一些代码,并设法使其工作。非常感谢你。我将上传一个简单的项目,在某个时候展示解决方案。干杯。此解决方案的性能影响是什么?我正在研究这在Lucene中是正常的还是强制对索引进行完全扫描。