2013-02-19 64 views
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,我收到thie错误:

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

回答

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类,因为我注意到,你对名称和CREATEDATE性质上面的文档类。您只需将映射提供给Solr,以便将它们存储在适当的Solr字段中。请参阅SolrNet Mapping页面了解更多详情。

+0

佩奇,thnx为答案。但我怎样才能发送“文档”类与所有细节“附加”类?我必须将它们序列化为一个xml文件吗?以及我如何设置Solr.NET _schema.xml_中的字段?在文档中,**多值**字段描述为** ICollection **,但在我的情况下,它是** ICollection **。 – lewis 2013-02-19 18:58:45

1

我想你打算提取纯文本,HTML,DOC和其他丰富的文件。而您的错误消息来自XML解析器,试图解析不是XML的东西。

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

相关问题