如何指定Lucene.net布尔与,或,不是操作符从正常和,或,而不是变量

本文关键字:变量 操作符 net Lucene 何指定 布尔 | 更新日期: 2023-09-27 18:02:08

在我的项目中,我正在使用Lucence实现全文索引搜索。但是当我这样做的时候,我被Lucene布尔运算符与Normal和or区分开来的逻辑所困住了。

假设例如,如果我们正在搜索"我想要一支钢笔和铅笔",但默认情况下Lucene.net搜索Lucene或操作。所以它会像那样搜索"我想要一支或钢笔或铅笔"而不是像那样搜索"我想要一支或钢笔或或铅笔"。那么,我们如何区分普通的和或不是Lucene操作符呢?

对于这个,我已经做了一个助手方法,看起来像
/// <summary>
    /// Method to get search predicates
    /// </summary>
    /// <param name="searchTerm">Search term</param>
    /// <returns>List of predicates</returns>
    public static IList<string> GetPredicates(string searchTerm)
    {
        //// Remove unwanted characters
        //searchTerm = Regex.Replace(searchTerm, "[<(.|'n)*?!'`>]", string.Empty);
        string exactSearchTerm = string.Empty,
               keywordOrSearchTerm = string.Empty, 
               andSearchTerm = string.Empty, 
               notSearchTerm = string.Empty,
               searchTermWithOutKeywords = string.Empty;
        //// Exact search tern
        exactSearchTerm = "'"" + searchTerm.Trim() + "'"";
        //// Search term without keywords
        searchTermWithOutKeywords = Regex.Replace(
            searchTerm, " and not | and | or ", " ", RegexOptions.IgnoreCase);
        //// Splioted keywords
        string[] splittedKeywords = searchTermWithOutKeywords.Trim().Split(
            new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
        //// Or search term
        keywordOrSearchTerm = string.Join(" OR ", splittedKeywords);
        //// And search term
        andSearchTerm = string.Join(" AND ", splittedKeywords);
        //// not search term
        int index = 0;
        List<string> searchTerms = (from term in Regex.Split(
                                        searchTerm, " and not ", RegexOptions.IgnoreCase)
                                        where index++ != 0
                                        select term).ToList();
        searchTerms = (from term in searchTerms
               select Regex.IsMatch(term, " and | or ", RegexOptions.IgnoreCase) ?
               Regex.Split(term, " and | or ", RegexOptions.IgnoreCase).FirstOrDefault() : 
               term).ToList();
        notSearchTerm = searchTerms.Count > 0 ? string.Join(" , ", searchTerms) : "'"'"";
        return new List<string> { exactSearchTerm, andSearchTerm, keywordOrSearchTerm, notSearchTerm };
    }

,但它将返回四个结果。所以我要循环遍历索引4次,但这似乎是非常繁忙的一次。有人能帮忙在单循环中解决这个问题吗?

如何指定Lucene.net布尔与,或,不是操作符从正常和,或,而不是变量

就像@Matt Warren建议的那样,lucene有所谓的"停止词",通常对搜索质量没有什么价值,但会使索引变得巨大和臃肿。像"a, and, or, the, an"这样的停止词通常会在索引时自动从文本中过滤掉,然后在解析时从查询中过滤掉。在这两种情况下,StopFilter都负责这种行为,但是您可以选择一个不使用StopFilter的分析器。

另一个问题是查询解析。如果我没记错的话,lucene查询解析器只会把大写的ORANDNOT当作关键字,所以如果用户输入的都是大写字母,你需要用小写字母替换它们,这样它就不会被当作操作符。这里有一些正则表达式。替换代码:

string queryString = "the red pencil and blue pencil are both not green or brown";
queryString = 
   Regex.Replace (
       queryString, 
       @"'b(?:OR|AND|NOT)'b", 
       m => m.Value.ToLowerInvariant ());

内置的StandardAnalyzer将为您剥离常见单词,请参阅本文以获得解释。