在索引时查询Solr会导致索引中的文档丢失

本文关键字:索引 文档 查询 Solr | 更新日期: 2023-09-27 18:03:27

我写了一个简单的。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();

"文档。GetFilesText" -这是一个字段,存储从pdf文件中提取的文本。
此示例清除了日志记录方法(写入Windows事件日志)。在索引时,我注意到:
a)事件日志——显示文档索引进度
b)"Solr Admin"webapp中的"Core Admin"页面-显示索引

中的文档计数

当我只是索引文档时,没有搜索,所有工作正常-事件日志显示"7500文档添加"条目,"核心管理"显示num docs = 7500

但是,如果我尝试在索引期间搜索文档,我有这些错误:
-搜索结果不包含所有传递的文档
- "Core Admin"重置num docs值。例如,EventLog显示7500个文档索引,但"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: to make things clear我有这些行在我的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索引中的文档全部丢失:-)

在索引时查询Solr会导致索引中的文档丢失

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

solr.Delete(SolrQuery.All)

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

可能有几个选项可以帮助您减轻这个问题。

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