我需要一些帮助来执行搜索。假设我有一个非常简单的文档结构,只有1个字段,标签名称。 我需要检索长度大于或小于指定值的所有名称。通过长度我的意思是String.length()。 范围过滤器在概念上似乎很接近,但我找不到一个很好的例子来写我的具体情况。 感谢您的帮助。Lucene:按字段值长度搜索/筛选
回答
使用长度添加NumericField,然后使用RangeQuery。有关示例,请参阅NumericField javadoc's。
这是一个MultiTermQuery的经典示例。它不在框中,但很容易实现。看看WildCardQuery
,它延伸MultiTermQuery
。这做了非常相似的事情。只需使用不同的FilterredTermEnum,就像使用term.text的长度来过滤术语(而不是术语文本本身)。
魔术在这里发生(此代码是在自定义项枚举在帖子的底部):
protected internal override bool TermCompare(Term term)
{
if (field == term.Field())
{
System.String searchText = term.Text();
if (searchText.Length >= text.Length())
{
return true;
}
}
endEnum = true;
return false;
}
上面的代码看起来通过对现场所有的条款,并检查它们的长度对长度该术语在构造函数中传递。它适用于任何至少有那么长的领域。
public class MinLengthQuery : MultiTermQuery
{
public MinLengthQuery(Term term) : base(term)
{
}
protected internal override FilteredTermEnum GetEnum(IndexReader reader)
{
return new MinLengthTermEnum(reader, GetTerm());
}
}
该类完成所有的工作:
public class MinLengthTermEnum : FilteredTermEnum
{
internal Term searchTerm;
internal System.String field = "";
internal System.String text = "";
internal System.String pre = "";
internal int preLen = 0;
internal bool endEnum = false;
public MinLengthTermEnum(IndexReader reader, Term term):base()
{
searchTerm = term;
field = searchTerm.Field();
text = searchTerm.Text();
SetEnum(reader.Terms(new Term(searchTerm.Field(), "")));
}
protected internal override bool TermCompare(Term term)
{
if (field == term.Field())
{
System.String searchText = term.Text();
if (searchText.Length >= text.Length())
{
return true;
}
}
endEnum = true;
return false;
}
public override float Difference()
{
return 1.0f;
}
public override bool EndEnum()
{
return endEnum;
}
public override void Close()
{
base.Close();
searchTerm = null;
field = null;
text = null;
}
}
(我是一个lucene.net的家伙,但翻译应该可以很容易做到......它可能会更容易入手您的Lucene WildCardQuery和TermEnum源代码的版本,并从中获益)。
非常感谢您的详细解答!将它转换为java确实很容易。 但我认为存在一个问题:这里假设条款是按枚举标准排序的,我不认为是这种情况。 如果该指数具有以下内容: AAAA aaaabbbb BBBB ......和查询请求长度小于5看起来这将停在第二个元素枚举和错过第三次。 我调整你的endEnum()方法使用return actualEnum.term()== null;而且工作起来,但似乎是将索引搜索转换为该术语的线性搜索。 – Federico
我用一个简单的查询和一个小型数据库(约17k文档)对它进行了测试,并添加了这个标准将查询时间从<10ms改为284ms。 我可以通过它添加一个长度字段和索引,但现在非常接近最初的建议。 你觉得呢? – Federico
看起来像我不明白,以及我认为的东西。我在这里从臀部射击,但不应该确保它正在查看正确的字段......否则,它会不会继续到下一个字段?('actualEnum.term()。field()= = expectedField || actualEnum.term()== null')。我认为TermEnumerator将从一个领域开始,遍历该领域的所有术语,然后前进到下一个领域......直到达到最后一个领域的最后一个领域。 –
- 1. Lucene - 搜索数值字段
- 2. 基于特定字段筛选lucene搜索
- 3. Zend Lucene仅在指定字段中使用筛选器搜索
- 4. 按Lucene中的字段搜索
- 5. 按长度和值筛选SQL Server 2014
- 6. 在lucene中搜索首选字段
- 7. Lucene按数值搜索
- 8. Zend搜索Lucene - 搜索特定字段
- 9. Lucene搜索2字段
- 10. 在Lucene中搜索字段
- 11. Lucene搜索所有字段
- 12. MVC搜索按照字母筛选
- 13. Sitecore.ContentSearch按字段值搜索
- 14. 在多个字段上使用角度搜索筛选器
- 15. 如何按值长度搜索SQL?
- 16. 搜索无字段长度标准化
- 17. Lucene索引字段不可搜索
- 18. Lucene多值字段索引
- 19. Lucene搜索采取TOOO长
- 20. 搜索多个数字字段Lucene
- 21. 在Zend中增强字段搜索Lucene
- 22. 在Lucene中搜索TokenStream字段
- 23. Zend Lucene搜索相关字段?
- 24. Lucene中的多字段搜索
- 25. Symfony lucene独立搜索字段
- 26. 如何在apache lucene中搜索非索引字段搜索
- 27. elasticsearch根据字符串字段的长度来筛选
- 28. 如何根据字段的字符长度筛选行
- 29. 使用筛选器在角度搜索
- 30. 角度搜索筛选结果
最简单的解决方案似乎是创建包含长度的第二个字段。我不确定'name'字段的索引可以如何有效地查询其长度。 – biziclop
我想我可以创建该字段,通过它索引,然后做一个范围过滤器/查询。在我看来,应该有一个更直接的解决方案,但这是一个很好的建议。 – Federico
可能有一个更直接的解决方案,我只是一个新手Lucene(这就是为什么我写我的建议作为一个评论,而不是一个答案),但这当然是我会做的。 – biziclop