【问题标题】:Find all available values for a field in lucene .net在 lucene .net 中查找字段的所有可用值
【发布时间】:2011-09-06 23:39:43
【问题描述】:

如果我有一个字段 x,它可以包含一个值 y 或 z 等,有没有一种方法可以查询,以便我可以只返回已被索引的值?

示例 x 可用的可设置值 = test1, test2, test3, test4

第 1 项:字段 x = test1

第 2 项:字段 x = test2

第 3 项:字段 x = test4

第 4 项:字段 x = test1

执行所需的查询将返回以下列表: 测试1,测试2,测试4

【问题讨论】:

    标签: lucene lucene.net


    【解决方案1】:

    我之前已经将其作为扩展方法实现过:

    public static class ReaderExtentions
    {
        public static IEnumerable<string> UniqueTermsFromField(
                                              this IndexReader reader, string field)
        {
            var termEnum = reader.Terms(new Term(field));
    
            do
            {
                var currentTerm = termEnum.Term();
    
                if (currentTerm.Field() != field)
                    yield break;
    
                yield return currentTerm.Text();
            } while (termEnum.Next());
        }
    }
    

    您可以像这样非常轻松地使用它:

    var allPossibleTermsForField = reader.UniqueTermsFromField("FieldName");
    

    这会让你得到你想要的。

    编辑:由于心不在焉,我跳过了上面的第一个学期。我已经相应地更新了代码以使其正常工作。

    【讨论】:

    • 此解决方案与在 Lucene 中使用 FieldCache 的方法有何不同? String[] fieldValues = FieldCache.DEFAULT.getStrings(indexReader, fieldname);
    • @basZero 使用 TermEnum 在一般情况下工作,即每个字段可能有多个值并且不消耗内存来将值存储在缓存中。
    • 有Java解决方案吗?
    • 请注意,在 lucene++ 中,如果读者没有返回任何术语,这将在 currentTerm.field 上失败。不确定这是否在 lucene.net 中得到妥善处理。
    【解决方案2】:
    TermEnum te = indexReader.Terms(new Term("fieldx"));
    do
    {
        Term t = te.Term();
        if (t==null || t.Field() != "fieldx") break;
        Console.WriteLine(t.Text());
    } while (te.Next());
    

    【讨论】:

    • indexReader.Terms 定位第一个词。如果您在访问该术语之前调用 Next in,您将失去第一个术语
    【解决方案3】:

    如果字段被索引为字符串或使用 KeywordTokenizer 而不使用过滤器进行索引,则可以使用构面返回字段的前 N ​​个值。这意味着该字段没有被标记化,而是按原样保存。

    只需在查询中设置以下属性:

    facet=true
    facet.field=fieldname
    facet.limit=N //the number of values you want to retrieve
    

    【讨论】:

      【解决方案4】:

      我认为在字段“x”和“*”值上搜索 WildcardQuery 可以解决问题。

      【讨论】:

      • 如果您的第一个字符为“*”,则不允许使用通配符查询。
      • 至少对于 Lucene.Net 2.9.2 不是这样。它很慢,因为它必须访问每个文档。 stackoverflow.com/questions/3412585/…
      【解决方案5】:

      我曾经使用过 Lucene 2.9.2,在那里我使用了 Manning 在“Lucene in Action”一书中描述的 FieldCache 方法:

      String[] fieldValues = FieldCache.DEFAULT.getStrings(indexReader, fieldname);

      数组fieldValues 包含字段fieldname 的索引中的所有值(例如:["NY", "NY", "NY", "SF"]),因此现在由您决定如何处理该数组。通常您会创建一个 HashMap&lt;String,Integer&gt; 来汇总每个可能值的出现次数,在本例中为 NY=3,SF=1。

      也许这会有所帮助。对于非常大的索引(索引中的 1.000.000 个文档)来说,它非常缓慢且占用内存,但它可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-20
        • 1970-01-01
        • 1970-01-01
        • 2014-01-29
        • 1970-01-01
        • 2013-05-16
        • 2014-05-09
        相关资源
        最近更新 更多