0

我正在尝试在我的 .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. 我必须序列化我的数据对象以索引它们吗?如果是,我必须如何在“附加”类中表示文件?
4

2 回答 2

2

要回答您的问题:

  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 映射页面。

于 2013-02-19T14:00:53.093 回答
1

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

使用 设置为URL的提取请求处理程序/update/extract

于 2013-02-19T12:05:07.553 回答