如何使用Lucene查询CSV字段

时间:2013-08-23 10:43:19

标签: csv lucene umbraco

我们正在使用Umbraco,它内置了一个基于Lucene的内置搜索系统。

网站上的每个文档都包含一个标签列表,这些标签由Luence索引并保存为包含CSV格式标签的单个字段。

例如:

Red,Green,Blue

然而,当我们通过Umbraco(也使用Luke)搜索此字段时,我们无法获得正确的行为。

搜索“红色”有效,但搜索“绿色”或“蓝色”不起作用。

根据我对Lucene的理解,这完全取决于分析师不理解CSV格式。分析器需要使用逗号标记以分解标记。

然而,我对如何实现这一点感到茫然。

似乎它必须是一个常见问题,所以我必须遗漏一些非常明显的问题。

2 个答案:

答案 0 :(得分:0)

我最近刚刚建立了一个Umbraco 6.1.3网站。标签被添加到文档类型的“标签”属性中,这些属性以逗号分隔格式编制索引。

Umbraco网站具有所有默认索引设置,因此不会修改任何内容。

当我在Luke中打开“外部”内容索引时,我可以看到“tags”字段是Indexed,Stored和Tokenized(以及其他内容),并且值按预期存储:

enter image description here

如果我使用tags:loremtags:ipsum在Luke中搜索,则会返回正确的结果。

如果你的标签字段没有被标记化,那么我会检查你正在使用的分析仪。 Lucene.Net.Analysis.Standard.StandardAnalyzer是首选,因为它会考虑到这一点。我很确定WhitespaceAnalyzer不会。

或者,您可以截取“索引”事件中的Umbraco文档,创建一个名为“tags_mod”的新Lucene字段并添加tags.Replace(",", ", ")。这样他们就应该正确编入索引。你当然必须搜索“tags_mod”而不是“标签”。这感觉有点hacky但完全有效。这是将文本内容组合到单个可索引字段中的一种很好的方法,例如,如果几个字段都具有相同的偏差,则无需索引,标记化并将它们全部分开存储。

答案 1 :(得分:0)

您是正确的,CSV不适用于Lucene。正如Umbraco forum所讨论的,您需要将函数绑定到GatheringNodeData Examine事件,这允许您进行自定义索引。

您可以使用此函数按空格而不是逗号分割CSV字段,将此数据作为新索引字段插入并将其包含在examineIndex.config的<IndexUserFields>部分

public class ExamineEvents : IApplicationStartupHandler
{
    public ExamineEvents()
    {
        ExamineManager.Instance.IndexProviderCollection[INDEX_NAME].GatheringNodeData
         += ExamineEventsGatheringNodeData;
    }

    void ExamineEventsGatheringNodeData(object sender, IndexingNodeDataEventArgs e)
    {
        if (e.IndexType == IndexTypes.Content)
        {
            var node = new Node(e.NodeId);                
            IndexCsv(e, node);                
        }
    }

    private void IndexCsv(IndexingNodeDataEventArgs e, Node node)
    {
        if (node.NodeTypeAlias == "CsvPropertyDocType" &&
           !string.isNullOrEmpty(node.GetPropertyValue("CsvProperty")))
        {
            e.Fields.Add("CsvFieldSearchable", node.GetPropertyValue("CsvProperty").Replace(","," "));
        }
    }
}

其中CsvProperty是CSV属性的名称,CsvPropertyDocType是包含该属性的文档类型的名称,INDEX_NAME是您的检查索引名称。