【问题标题】:Indexing data inside database, with files stored on filesystem索引数据库内的数据,文件存储在文件系统上
【发布时间】:2013-02-19 04:13:08
【问题描述】:

我正在尝试在我的 .NET 应用程序中使用 Apache Solr 作为全文搜索引擎(通过 SolrNet)。 我的应用程序具有这种数据模式:

class Document 
{
    public int Id { get; set; };
    public string Name { get; set; }
    public DateTime CreateDate { get; set;}
    public Attach[] Attaches { get; set; }
}

class Attach
{
    public int Id { get; set; }
    public Document Parent { get; set; }
    //files are stored in filesystem, only path stored in database!
    public string FilePath { get; set; }
}

现在,我正在尝试索引这些文件(使用 Castle.Windsor):

_container.AddFacility("solr", 
    new SolrNetFacility("http://localhost:8983/solr"));
var solr = _container.Resolve<ISolrOperations<Document>>();
solr.Delete(SolrQuery.All);

var conn = _container.Resolve<ISolrConnection>();

var docs = from o in Documents
           where o.Attaches.Count > 0
           select o;

foreach (var doc in docs)
{
    foreach (var att in doc.Attaches)
    {
        try
        {
            var file = Directory.GetFiles("C:\\Attachments\\" + doc.Id );
            foreach (var s in file)
            {
                var a = File.ReadAllText(s);
                conn.Post("/update", a);    
            }

        }
        catch (Exception)
        {           
            throw;
        }
    }
}
solr.Commit();
solr.BuildSpellCheckDictionary();

如代码中所述,我正在搜索文件路径,并直接从磁盘添加文件内容。但是,当我将文件的文本发布到 Solr 时,我收到了错误:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <lst name="responseHeader">
        <int name="status">400</int><int name="QTime">2</int>
    </lst>
    <lst name="error">
        <str name="msg">Unexpected character 'Т' (code 1058 / 0x422) in prolog; expected '&lt;'
 at [row,col {unknown-source}]: [1,1]</str>
        <int name="code">400</int>
    </lst>
</response>

我有这个问题:

  1. 我可以发布到索引纯文本,而不是 XML?
  2. 我必须序列化我的数据对象以索引它们吗?如果是,我必须如何在“附加”类中表示文件?

【问题讨论】:

    标签: c# .net solr castle-windsor solrnet


    【解决方案1】:

    回答您的问题:

    1. 是的,您可以将纯文本发布到索引。
    2. 您发布的项目必须经过序列化(默认为 XML,但也可以使用 JSON)才能将它们添加到索引中。

    从您的示例代码看来,您似乎只对文件的纯文本进行索引感兴趣。基于此,我将创建以下类用于将数据传递给 Solr。

      public class IndexItem
      {
           [SolrField("id")]
           public string Id { get; set; }
    
           [SolrField("content")]
           public string Content { get; set; }
      }
    

    使用此类存储您读取的每个文件的 Id(必须是唯一值)。文件名(也包括路径)可能足够独特。

    将您的示例更改为以下内容:

    _container.AddFacility("solr", 
        new SolrNetFacility("http://localhost:8983/solr"));
    var solr = _container.Resolve<ISolrOperations<IndexItem>>();
    solr.Delete(SolrQuery.All);
    
    var docs = from o in Documents
               where o.Attaches.Count > 0
               select o;
    
    foreach (var doc in docs)
    {
        foreach (var att in doc.Attaches)
        {
            try
            {
                var file = Directory.GetFiles("C:\\Attachments\\" + doc.Id );
                foreach (var s in file)
                {
                           var indexItem = new IndexItem();
                           indexItem.Id = s.FileName;
                           indexItem.Content = File.ReadAllText(s);
                           solr.Add(indexItem);    
                }
    
            }
            catch (Exception)
            {           
                throw;
            }
        }
    }
    solr.Commit();
    solr.BuildSpellCheckDictionary();
    

    如果您需要为每个文件索引更多附加属性,您可以将它们添加到 IndexItem 类,因为我注意到您在上面的 Document 类中有 Name 和 CreateDate 属性。您只需提供到 Solr 的映射,以便将它们存储在适当的 Solr 字段中。请参阅SolrNet Mapping 页面了解更多详情。

    【讨论】:

    • 佩奇,谢谢回答。但是我如何发送带有所有详细“附加”类的“文档”类?我必须将它们序列化为一个 xml 文件吗?以及如何在 Solr.NET schema.xml 中设置字段?在文档中,multivalued 字段描述为 ICollection,但在我的例子中是 ICollection
    【解决方案2】:

    我猜你打算提取纯文本、HTML、DOC 和其他富文档。您的错误消息来自试图解析非 XML 内容的 XML 解析器。

    使用设置为/update/extract URL 的extracting request handler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-14
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 1970-01-01
      • 2012-08-29
      相关资源
      最近更新 更多