我目前正处于一个相当大的基于问题/答案的应用程序中(有点像stackoverflow / answerbag.com) 我们使用SQL(Azure)和nHibernate进行数据访问,使用MVC进行UI应用。
到目前为止,架构基本上与stackoverflow db一致,因为我们有一个 Post 表(包含问题/答案)
可能会使用以下存储库接口的内容:
public interface IPostRepository
{
void PutPost(Post post);
void PutPosts(IEnumerable<Post> posts);
void ChangePostStatus(string postID, PostStatus status);
void DeleteArtefact(string postId, string artefactKey);
void AddArtefact(string postId, string artefactKey);
void AddTag(string postId, string tagValue);
void RemoveTag(string postId, string tagValue);
void MarkPostAsAccepted(string id);
void UnmarkPostAsAccepted(string id);
IQueryable<Post> FindAll();
IQueryable<Post> FindPostsByStatus(PostStatus postStatus);
IQueryable<Post> FindPostsByPostType(PostType postType);
IQueryable<Post> FindPostsByStatusAndPostType(PostStatus postStatus, PostType postType);
IQueryable<Post> FindPostsByNumberOfReplies(int numberOfReplies);
IQueryable<Post> FindPostsByTag(string tag);
}
我的问题是: 在哪里/如何使用solr来更好地查询这些“帖子” (我将使用solrnet与Solr进行实际通信)
理想情况下,我将SQL db仅用作持久存储 - 上面的大部分IQueryable操作都将转移到某种SolrFinder类(或类似的东西)
Body属性是导致当前问题的属性 - 它相当大,并且减慢了对sql的查询。
我的主要问题是,例如,如果有人“更新”帖子 - 例如,添加新标签,那么整个帖子将需要重新编制索引。 显然,这样做需要这样的查询:
“SELECT * FROM POST WHERE ID = xyz”
这当然会很慢。 Solrnet有一个nHibernate工具 - 但我相信这与上面结果相同?
我想到了解决这个问题的方法,我希望你对此有所了解:
我的设计遇到了另一个问题: 应该从哪里调用“重新索引”方法? MVC控制器?或者我应该有一个“PostService”类型类,它包装了IPostRepository的实例?
这个指针很受欢迎!
答案 0 :(得分:27)
答案 1 :(得分:8)
我们使用solr来查询大型产品数据库。 大约100万件产品和30家商店。
我们所做的是在产品表和Sql服务器上的库存表中使用了触发器。
每次更改行时,都会标记要重新编制索引的产品。我们有一个窗口服务,抓住这些产品,并每隔10秒发布到Solr。 (每批限量100件产品)。
这是股票的超高效,几乎实时的信息。
答案 2 :(得分:2)
如果你有一个大文本字段(你的'body'字段),那么是,在后台重新索引。您提到的解决方案(队列或定期后台服务)将会这样做。
MVC控制器应该忘记这个过程。
我注意到您的存储库界面中有IQueryables。 SolrNet目前不是have a LINQ provider。无论如何,如果这些操作都与Solr有关(即没有分面),你可能需要考虑使用Lucene.Net, 有一个LINQ提供者。