将文档存储用作缓存

问题描述:

我设置了ElasticSearch的基本实现,在文档中存储了几个字段,并且能够执行查询。将文档存储用作缓存

var searchResult = client.Search<SearchTest>(s => 
    s 
    .Size(1000) 
    .Fields(f => f.ID) 
    .Query(q => q.QueryString(d => d.Query(query))) 
    ) 
    .Documents.Select(item => 
     item.ID 
     ) 
    .ToList(); 

var products = this.DbContext.Products 
    .Where(item => 
     searchResult.Contains(item.ProductId) 
     && ... 
     ) 
    .Select(item => ...); 

// subsequent queries here 

现在,我只是返回索引,我用它在数据库查询中检索大量信息。存储在文件中的信息也被检索。现在我想知道,我应该跳过从数据库中检索这个,并使用文档存储中的数据吗?或者我应该使用它除了搜索?

一些上下文:在产品数据库中搜索时,某些信息总是相同的,某些信息(如价格计算)取决于哪个客户正在搜索。

这个问题并没有真正的硬性和快速的答案。我喜欢从索引中提取足够的信息来填充搜索结果列表,但是可以从其他人,外部资源(例如数据库)中检索文档的完整内容。完全主观地看,这似乎是我见过的Lucene更常见的用法。

据我所知,存储策略不应该直接影响搜索性能,但将每个文档存储的数据保持在最低限度可以提高从索引中检索文档的性能(例如,提到的结果列表之前)。

我也有时犹豫让Lucene成为记录系统。发现自己的索引比数据库损坏/损坏要容易得多。我喜欢有可用的选项来垃圾和重建它。

我看到你已经接受了答案,但我想提供第二种方法。 Elasticsearch擅长存储文档(json),因此检索完整的对象图可能是一种非常快速且功能强大的方法来克服阻抗不匹配和N + 1敏感的数据库查询。

对我来说,最好的方法是使searchResults已经成为明确的IEnumerable<Product>的列表,之后不必进行N个数据库查询。

Elasticsearch(与原始lucene甚至Solr不同)有一个专门的字段,用于存储名为_source的原始json图,因此加载整个文档的开销非常小。

这样做的代价是必须将数据基本写入两次,一次写入数据库,一次写入每次突变的弹性搜索。根据你的架构,这可能或不可能实现。

我同意@femtoRgon能够从外部数据源进行重新索引是一个好主意,但Elasticsearch开发人员正在努力工作以获得适当的备份和恢复为1.0。这将大大减少对第二个数据存储的需求。

顺便说一句,不知道你是否知道,但指定.Fields()已经强制Elasticsearch只加载指定的字段,而不是来自特殊_source字段的整个图表。

+0

有很多遗留代码已经使用(和修改)这些数据,现在还不清楚我们是否可以写入ES或者是否需要间隔地重新索引。谢谢(你的)信息! – Stijn