我正在使用.NET开发一个高级搜索引擎,用户可以根据以下几个字段生成查询:
头衔
文件内容
日期从,日期到
从修改日期到修改日期
所有者
位置
其他元数据
我使用lucene为文档内容及其相应的id编制索引。但是,其他元数据位于ms sql db中(以避免扩大索引,并在对元数据进行任何修改时不断更新索引)。
如何执行搜索?
当任何用户搜索术语时:
通过在sql db中查找,根据用户选择的条件缩小搜索结果的范围。
将匹配的id返回到lucene searcher web服务,该web服务搜索adv search web服务返回的documntids中输入的关键字。
然后再次在数据库中查找,获得文档id(从lucence返回)的相关元数据。
正如您在这里注意到的,在db中有一个查找,然后是lucene,最后是db以获取要在网格中显示的值。
问题:
如何克服这种情况?我本想开始搜索lucene,但如果索引的文档达到200万,这就有一个缺点。(我认为首先使用db缩小结果对性能有很大影响)。
另一个问题是将id传递给lucene搜索服务,传递几十万个id有多有效?还有其他的解决方案是什么?
我欢迎任何想法,所以请分享你的想法。

最佳答案

当前的解决方案在查询时会产生以下开销:
1)通过MS-SQL缩小搜索空间
在应用程序中生成查询
通过线路发送到MS-SQL
sql查询的解析/优化/执行
[!!]返回100000个ID的I/O开销
2)通过lucene.net执行有界全文搜索
[!!]lucene在app中生成/执行包含100000个id子句的大型booleanquery时的内存开销(您需要首先覆盖1024个子句的默认限制,才能度量此效果)
标准Lucene全文搜索执行
返回匹配的ID
3)通过MS-SQL实现结果细节化
搜索结果文档的快速、索引、基于id的查找(仅在显示结果的第一页需要,通常约10-25条记录)
你可能有两个假设值得重新考虑
a)索引所有元数据(日期、作者、位置等)将不可接受地增加索引的大小。
首先尝试一下:这是最佳实践,除了文本搜索之外,还可以让lucene为您执行所有过滤,从而大大减少查询执行开销。
此外,索引的大小主要与每个字段的基数有关。例如,如果只有500个唯一的所有者名称,那么将只存储这500个字符串,并且每个lucene文档将通过符号表查找(4字节整数*2 mm文档+500个字符串=b)MS-SQL查询将是过滤非文本元数据的最快方式。
重新考虑一下:使用适当的lucene类型正确地索引元数据,查询lucene与查询ms-sql不会产生任何额外的开销。(在某些情况下,lucene可能更快。)
您的里程数可能会有所不同,但根据我的经验,在lucene的2毫米文档集合上执行这种类型的过滤全文搜索时,运行时间通常不会超过100毫秒。
因此,总结最佳实践:
索引要查询或筛选的所有数据。(由于MS-SQL是您的记录系统,因此不需要存储源数据)。
对lucene运行过滤查询(例如文本和日期范围、所有者、位置等)
返回ID
使用返回的ID实现MS-SQL中的文档。
我还建议您考虑迁移到独立的搜索服务器(solr或elasticsearch),原因有很多:
您不必担心搜索索引内存需求会破坏应用程序内存需求。
您将利用复杂的过滤器缓存性能提升和基于操作系统的I/O优化。
您将能够从广泛使用/支持的主要基于配置的环境中轻松地迭代搜索解决方案。
您将拥有适当的工具来扩展/优化/备份/恢复搜索,而不会影响您的应用程序。

07-24 09:46
查看更多