1

我编写了简单的 .NET Windows 服务,它将文档推送到 Apache Solr v4.1。为了访问 Solr,我使用了 SolrNet。我的代码是:

var solr = _container.Resolve<ISolrOperations<Document>>();             
solr.Delete(SolrQuery.All);

var docs = from o in documents
           orderby o.Id ascending
           select o;

for (var i = 0; i < docs.Count(); i++ )
{
    var texts = new List<string>();
    if (docs.ToList()[i].DocumentAttachments.Count > 0)
    {
        foreach (var attach in docs.ToList()[i].DocumentAttachments)
        {
            using (var fileStream = System.IO.File.OpenRead(...))
            {
                var extractResult = solr.Extract(
                    new ExtractParameters(fileStream, attach.Id.ToString(CultureInfo.InvariantCulture))
                    {
                        ExtractFormat = ExtractFormat.Text,
                        ExtractOnly = true
                    }
                );
                texts.Add(extractResult.Content);                   
            }
        }
    }

    docs.ToList()[i].GetFilesText = texts;
    solr.Add(docs.ToList()[i]);

    if (i % _commitStep == 0)
    {
        solr.Commit();
        solr.Optimize();
    }
}

solr.Commit();
solr.Optimize();
solr.BuildSpellCheckDictionary();

“Document.GetFilesText” - 这是一个存储文本的字段,从 pdf 文件中提取。
此示例已从日志记录方法中清除(写入 Windows 事件日志)。在编制索引时,我会看到:
a) 事件日志 - 显示文档索引进度
b) “Solr Admin”webapp 中的“Core Admin”页面 - 显示索引中的文档数

当我只是索引文档而不搜索时,一切正常 - 事件日志显示“7500 docs added”条目,“Core Admin”显示num docs = 7500

但是,如果我在索引期间尝试搜索文档,我会遇到以下错误:
- 搜索结果不包含所有传递的文档
- “核心管理员”重置num docs值。例如,EventLog 显示7500 docs indexed,但“Core Admin”显示num docs=23。当我查询 Solr 时,每次都会重置num docs

我的查询代码:

searchPhrase = textBox1.Text;
var documents = Solr.Query(new SolrQuery(searchPhrase), new QueryOptions
    {
        Highlight = new HighlightingParameters
            {
                UsePhraseHighlighter = true,
                Fields = new Collection<string> { "Field1", "Field2", "Field3" },
                BeforeTerm = "<b>",
                AfterTerm = "</b>"
            },
        Rows = 100
    });

UPD:为了清楚 起见,我的 webapp 的“搜索”页面中有这些行:

public class MyController : Controller
{
    public ISolrOperations<Document> Solr { get; set; }

    public MyController()
    {
        //_solr = solr;
    }

    //
    // GET: /Search/My/
    public ActionResult Index()
    {
        Solr.Delete(SolrQuery.All);

        return View();
    }
...

而且,在浏览器中打开此页面会导致 Solr 索引中的文档完全丢失。:-)

4

1 回答 1

4

您看到这种行为是因为您要做的第一件事是清除索引。

solr.Delete(SolrQuery.All)

这将从索引中删除所有文档。因此,一旦重新索引开始,索引将为空。现在在您的后续代码中,您将项目分批添加回索引中。但是,在发出提交之前,查询索引的用户将看不到您添加到索引的任何新文档。由于您正在添加文档并在此期间批量发布提交,这解释了为什么在重建时您的文档数量会增加以及为什么不是所有文档都可见。在发出最后一次提交之前,您在索引中的计数和文档总数不会是 7500。

可能有几个选项可以帮助您缓解这种情况。

  1. 使用commitWithin向 Solr 发出软提交或向 Solr自动软提交。CommitWithin 支持作为 SolrNetAddParameter中 Add 方法的可选选项。你可以发出solr.Add(docs.ToList()[i], new AddParameters{ CommitWithin = 3000});which 会告诉 Solr 在 3 秒内提交这批项目。
  2. 使用Solr Cores拥有一个用户正在搜索的“活动”核心,并将您的日志数据重新加载到“备用”核心中。一旦对备用核心的加载过程完成,您可以发出命令来交换核心,这对任何用户都是完全透明的。SolrNet 也支持 CoreAdmin 命令,有关示例,请参阅SolrCoreAdminFixture.cs中的测试。

希望这可以帮助。

于 2013-03-12T18:45:41.813 回答