随着数据被创造为“新货币”,Apache Lucene 作为流行的全文搜索引擎获得了关注,广泛用于应用程序中,以对大量文本数据进行灵活的文本搜索。 Lucene 使用 倒排索引,大大减少了查找与特定术语相关的文档的时间。
NCache 更多信息 分布式 Lucene NCache 配套文档
然而,它是一个独立的解决方案,不会随着数据的增长而扩展——您需要重建整个 Lucene 索引来搜索数据,这是一项昂贵且缓慢的任务,成为性能瓶颈。 虽然现在存在一些基于 Java 和 REST 的解决方案来满足可扩展的全文搜索,但仍然缺乏自然适合 .NET 堆栈的可扩展的全文搜索解决方案。
将分布式 Lucene 与 NCache 对于.NET
NCache,一个功能强大且流行的 .NET 内存中数据存储,已经在其分布式架构上实现了本机 Lucene.NET API。由于它是标准的 Lucene.NET API,因此无需更改代码即可以可扩展的方式使用它 NCache.
NCache 还利用此 Lucene.NET 在动态可伸缩环境中创建索引以允许 分布式全文搜索. 这些搜索的结果在被发送回您的应用程序之前合并。
NCache 更多信息 分布式Lucene的工作 Lucene 组件和概述
这将独立的 Lucene 增强为快速且可线性扩展的全文搜索解决方案。
NCache 更多信息 用于企业搜索的分布式 Lucene 分布式 Lucene
在 .NET 应用程序中使用 Lucene
让我们考虑一个电子商务站点,该站点包含数千种产品、订单和客户详细信息的信息。 因此,索引所有属性,尤其是非文本字段(搜索时不使用)并不是明智的做法,因为它会耗尽缓存内存。
例如,我们的产品文档如下所示:
1 2 3 4 5 6 7 8 9 |
{ “ID”: “ABC34”, “Name”: “Tupperware”, “Description”: “Microwaveable, dishwasher-friendly, reusable Tupperware in three sizes”, “RetailPrice”: 15.00, “Discount”: 3.00 } |
现在,我们知道我们的客户对产品描述执行全文搜索,这是文档的一个字段。 那么,如果我们只索引那些可以搜索的字段,并且有一个键指向其在持久性存储(例如数据库或文件系统)中的相应文档呢? 这样,一旦您查询特定类型的产品,比方说“洗碗机友好的特百惠”,所有描述与这些术语匹配的产品都将以其 ProductID 作为文档键出现,然后可以从中获取整个文档持久索引。
要在现有应用程序中使用分布式 Lucene,您只需指定 NCache打开目录时的目录。 这需要 NCache 缓存名称和索引名称。 下面的代码片段在缓存 LuceneCache 中打开一个目录 NCache 和一个名为 ProductIndex 的索引。
1 2 3 4 5 6 7 |
// Specify the cache name and index path for Lucene string cache = "LuceneCache"; string index = "ProductIndex"; // Create directory and open it on the cache Directory directory = NCacheDirectory.Open(cache, index); |
Lucene 提供了一种广泛的查询语言,它将给定的字符串解释为 Lucene 查询。 这可以在一个术语、多个术语、通配符甚至模糊词上完成。 要了解有关 Lucene 查询的更多信息,请阅读 Lucene 查询文档.
以下代码片段在目录上创建一个 IndexReader,供 IndexSearcher 使用。 数据在 StandardAnalyzer 的基础上进行分析和标记化。 结果中的前 50 次匹配将返回到应用程序。 请注意,分析器必须与创建索引时使用的分析器相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// The 'applyAllDeletes' is true so all enqueued deletes are applied on writer IndexReader reader = DirectoryReader.Open(indexWriter, true); // A searcher is opened to perform searching IndexSearcher indexSearcher = new IndexSearcher(reader); // Specify the searchTerm, fieldName and analyzer string searchTerm = "Beverages"; string fieldName = "Category"; // Note that the analyzer should be same as the one used during index creation Analyzer analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48); // Create a query parser to parse the query QueryParser parser = new QueryParser(LuceneVersion.LUCENE_48, fieldName, analyzer); Query query = parser.Parse(searchTerm); // Returns the top 50 hits from the result set ScoreDoc[] docsFound = indexSearcher.Search(query, 50).ScoreDocs; reader.Dispose(); |
加载数据以构建分布式索引
使用 Lucene,您可以根据需要构建索引并将数据加载到其中。 索引需要一个分析器,它可以根据您的需要对数据进行分析和标记——它可以是空格、非字母、标点符号等。 为 Lucene 索引创建编写器后,您可以创建文档并向其添加字段。 该文档随后被编入索引 NCache 调用 Commit() 后作为分布式索引。 有关 Lucene 分析器的更多详细信息,请查看 Lucene 分析器文档.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Specify the cache name and index path for Lucene string cache = "LuceneCache"; string indexPath = "ProductIndex"; // Create directory and open it on the cache Directory directory = NCacheDirectory.Open(cache, indexPath); // The same analyzer is used as for the reader Analyzer analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48); IndexWriterConfig config = new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer); // Create indexWriter on NCache directory IndexWriter indexWriter = new IndexWriter(directory, config); Product[] products = FetchProductsToIndex(); foreach (var product in products) { Document doc = new Document { new StoredField("id", product.ID), new TextField("name", product.Name, Field.Store.YES), new TextField("description", product.Description, Field.Store.YES), new StringField("category", product.Category, Field.Store.No), new StoredField("retail_price", product.RetailPrice), }; indexWriter.AddDocument(doc); } indexWriter.Commit(); </code><br /><br /><a href="/ncache/">NCache Details</a> <a href="/resources/docs/ncache/prog-guide/lucene-ncache.html#working-of-distributed-lucene">Working of Distributed Lucene</a> <a href="/blogs/geospatial-indexes-for-distributed-lucene-with-ncache/">GeoSpatial Indexes for Distributed Lucene</a> |
为什么 NCache 用于分布式 Lucene?
运用 NCache 分布式 Lucene 为您提供以下好处:
- 极快且可线性扩展: NCache 是内存中的分布式数据存储,因此构建 分布式Lucene 除此之外,它还为您的全文搜索提供了相同的最佳性能。 此外,由于 NCache的分布式架构,Lucene 索引在集群的所有服务器上进行分区。 这使它具有可扩展性,因为随着数据负载的增加,您可以随时添加更多服务器,并且 Lucene 索引会自动 redis在没有任何客户干预的情况下致敬。
- 可靠性和高可用性的数据复制: NCache在 Partition-of-Replica 拓扑中,Lucene 索引不仅跨所有服务器进行分区,而且每个分区还被复制到集群的另一台服务器上。 因此,如果任何服务器出现故障,该分区的副本将为 t/resources/docs/ 的所有查询提供服务ncache/admin-guide/distributed-lucene-counters.html 索引,保证可靠性。 同样,如果服务器节点出现故障, NCache 动态自我修复 通过重新调整剩余节点内的数据,不会造成任何停机或影响您的 Lucene 索引,从而确保高可用性。
结论
总而言之,由于强大的搜索引擎 Lucene,全文搜索现在已成为几乎所有业务的基础。 但是随着数据的增长,重建索引可能会造成更大的损失而不是收益,而这在内存中,分布式 .NET 解决方案中,例如 NCache 只需在您现有的 Lucene 应用程序中更改一行代码,瞧,您拥有两全其美的内存分布式全文搜索机制。