【问题标题】:Memory Based Full Text Search基于内存的全文搜索
【发布时间】:2013-07-23 00:13:00
【问题描述】:

我有一个结构类似于博客的社交功能:帖子和 cmets。

帖子有一个名为 body 的字段,cmets 也是如此。帖子和 cmets 存储在 SharePoint 列表中,因此直接 SQL 全文查询不可用。

如果有人输入“11月份的停电恢复效率”,我真的不知道如何根据帖子的内容及其附加的cmets正确返回帖子列表。

好消息是,我一次需要搜索的帖子永远不会超过 50-100 个。知道这一点,解决这个问题的最简单方法是我将帖子和 cmets 加载到内存中并通过循环搜索它们。

理想情况下,这样的解决方案是最快的:

class Post
{
    public int Id;
    public string Body;
    public List<Comment> comments;
}
class Comment
{
    public int Id;
    public int ParentCommentId;
    public int PostId;
    public string Body;
}
public List<Post> allPosts;
public List<Comment> allComments;

public List<Post> postsToInclude (string SearchText)
{
    var returnList = new List<Post>();
    foreach(Post post in allPosts)
    {
        //check post.Body with bool isThisAMatch(SearchText, post.Body)
        //if post.Body is a good fit, returnList.add(post);
    }
    foreach(Comment comment in allComments)
    {
        //check post.Body with bool isThisAMatch(SearchText, comment.Body)
        //if comment.Body is a good fit, returnList.add(post where post.Id == comment.PostId);
    }
}

public bool isThisAMatch(string SearchText, string TextToSearch)
{
    //return yes or no if TextToSearch is a good match to SearchText
}

【问题讨论】:

    标签: c# search full-text-search


    【解决方案1】:

    这不是一个无关紧要的话题。由于机器没有“内容”的概念,因此很难检索到关于某个主题的文章。为了有根据地猜测每篇文章是否与您的搜索词相关,您必须使用一些代理算法,例如TF-IDF

    我建议不要自己实现,而是使用现有的信息检索库。那里有一些非常受欢迎的。根据我自己的经验,我建议仔细查看Apache Lucene。看看他们的reference list 就可以看出他们的重要性。

    如果您从未接触过信息检索,我保证您的学习曲线会非常陡峭。为了轻松进入整个区域,我建议您先使用Solr。它几乎是“开箱即用”的,让您对什么是可能的有一个很好的了解。当我开始真正研究可用的过滤器和算法的每一步时,我有了突破。在那之后,我对改变什么以获得更好的结果有了更好的理解。根据您内容的格式,系统可能需要认真调整。

    我在工作中花了很多时间在 Lucene、Solr 和一些替代品上。我最终得到的结果是可以接受的,但这是一个艰难的过程。它需要大量的理论、测试和原型设计才能到达那里。

    【讨论】:

    • 由于政策的原因,很难添加任何第三方 API。既然我不需要做任何索引,还有其他方法吗?感谢您的帮助:)
    • TF-IDF 似乎是一个从文档中挖掘关键字的过程。它可能适合也可能不适合这里。
    • 我可以根据经验告诉您,基于内容的搜索非常复杂。您将无法重新创建其他人花费数年开发的东西。 TF-IDF 让您了解搜索词中某个词的相关程度。在您的示例中,“in”远不如“restoration”重要。通过比较每条记录 (TF) 和所有记录 (IDF) 的频率分析,将“不太重要”转换为用于按相关性排序的数值。
    【解决方案2】:

    注意:我没有这样做的经验,但这是我解决问题的方法。

    首先,我会并行进行搜索。通过这样做,它将大大提高您的搜索功能的性能。

    其次,因为您可以输入多个单词,所以我将创建一个评分系统,根据查询对评论进行评分。例如,如果 cmets 有 2 个查询词,则它的得分值高于仅包含 1 个查询词的评论。或者,如果评论包含完全匹配,也许它可能会获得非常高的分数。

    无论如何,一旦基于并行循环中的查询输入对所有 cmets 进行评分,就会向用户显示排名靠前的 cmets 作为其结果。另外请注意,这是因为数据集规模较小,50-100。

    【讨论】:

    • 我可以向你保证,这并不容易。您必须考虑很多不同的方面,以使您最好使用现有系统。
    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多