Lucene:找到最接近的数字
Lucene: Find closest number
我正在使用 Lucene.Net ver 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
搜索范围内数字的方法,但这对我没有帮助,因为它不允许输入接近值,只能输入 mix
和 max
:
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
您将面临的问题:
- 没有
DualFloatFunction
是 Lucene.Net,因此您需要以某种方式使用您拥有的 already. The one that looks most promising to me is ReciprocalFloatFunction。另一种方法是实现您自己的 DualFloatFunction。
总体结论 - 这是可能的,但您需要花一些时间将其采用到 C# 和 Lucene.Net。
解决方案的完整来源位于 here。
我正在使用 Lucene.Net ver 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
搜索范围内数字的方法,但这对我没有帮助,因为它不允许输入接近值,只能输入 mix
和 max
:
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
您将面临的问题:
- 没有
DualFloatFunction
是 Lucene.Net,因此您需要以某种方式使用您拥有的 already. The one that looks most promising to me is ReciprocalFloatFunction。另一种方法是实现您自己的 DualFloatFunction。
总体结论 - 这是可能的,但您需要花一些时间将其采用到 C# 和 Lucene.Net。
解决方案的完整来源位于 here。