使用文档存储作为缓存

时间:2013-07-02 09:29:57

标签: lucene elasticsearch nest

我已经设置了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

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

某些情况:在产品数据库中搜索,某些信息始终相同,某些信息(如价格计算)取决于哪个客户正在搜索。

2 个答案:

答案 0 :(得分:1)

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

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

我有时也犹豫不决让Lucene成为唱片系统。使用损坏/损坏的索引而不是数据库来发现自己似乎要容易得多。我喜欢使用垃圾桶并重建它。

答案 1 :(得分:1)

我看到你已经接受了答案,但我想提供第二种方法。

Elasticsearch擅长存储文档(json),因此检索完整的对象图可以是一种非常快速且强大的方法来克服阻抗不匹配和N + 1敏感数据库查询。

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

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

这需要基本上将数据写入两次,一次写入数据库,一次写入弹性搜索。根据您的架构,这可能会或可能不会实现。

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

BTW不确定您是否知道但指定.Fields()已经迫使Elasticsearch仅加载指定字段而不是特殊_source字段中的整个图表。