C# 在Lucene搜索结果中查找项目位置的最佳方法

C# 在Lucene搜索结果中查找项目位置的最佳方法,c#,.net,lucene,C#,.net,Lucene,我使用的是Lucene.NET,能够以ScoreDoc[]的形式搜索并获得命中结果 我需要知道ScoreDoc[]中的具体项目位置。ScoreDoc[]中的所有项目都是唯一的 示例代码: luceneSearcher.Search(查询、收集器); ScoreDoc[]分数=收集器.TopDocs().scoreDocs 例如,我需要在ScoreDoc[]中获取find item position,它具有自定义ID属性,其中值可以是“99999” 我可以遍历scores[]中的项,检查与'999

我使用的是Lucene.NET,能够以ScoreDoc[]的形式搜索并获得命中结果

我需要知道ScoreDoc[]中的具体项目位置。ScoreDoc[]中的所有项目都是唯一的

示例代码: luceneSearcher.Search(查询、收集器); ScoreDoc[]分数=收集器.TopDocs().scoreDocs

例如,我需要在ScoreDoc[]中获取find item position,它具有自定义ID属性,其中值可以是“99999”

我可以遍历scores[]中的项,检查与'99999'匹配的ID属性,然后返回位置,但这可能会影响性能,因为scores[]可以有数千个项

还有更好的技术吗


谢谢

我想到了创建一个新的ExtendedCollector来存储收集的文档

    public class ExtendedCollector : Collector
    {
        private Scorer _scorer;
        private Int32 _docBase;
        private List<CollectedDocument> _documents;

        public ExtendedCollector()
        {
            _documents = new List<CollectedDocument>();
        }

        public override void SetScorer(Scorer scorer)
        {
            _scorer = scorer;
        }

        public override void Collect(int doc)
        {
            var docId = _docBase + doc;
            var score = _scorer.Score();

            var currentDoc = _documents.FirstOrDefault(d => d.DocId == docId);

            if (currentDoc == null)
                _documents.Add(new CollectedDocument()
                                   {DocId = docId, Score = score, OriginalIndex = _documents.Count, Index = _documents.Count});
            else
                currentDoc.Score = score;
        }

        public override void SetNextReader(IndexReader reader, int docBase)
        {
            _docBase = docBase;
        }

        public override bool AcceptsDocsOutOfOrder()
        {
            return false;
        }

        public List<CollectedDocument> Documents
        {
            get { return _documents; }
        }

        public List<CollectedDocument> DocumentsByScore
        {
            get
            {
                var result = _documents.OrderByDescending(d => d.Score).ToList();
                var itemId = 0;
                foreach (var collectedDocument in result)
                {
                    itemId++;
                    collectedDocument.Index = itemId;
                }

                return result;
            }
        }
    }
无论什么时候你想得到结果,你都会去做

        var myCollector = new ExtendedCollector();
        searcher.Search(searchQuery, myCollector);

        foreach (var doc in myCollector.Documents)
        {
            var docIndex = doc.Index; //this is the current index in a list
            var originalIndex = doc.OriginalIndex; //this is item Id set when doc was collected
        }
您还可以使用按分数排序的文档

myCollector.DocumentsByScore

这可能不是最简单的解决方案,但它确实有效。如果有人有更好的解决方案,请发布,因为我也想知道。

老实说,我没有看到,但会调查它。你为什么要找到
99999
的位置。你真正的问题是什么?我有一个虚拟控件,我需要显示一个特定的项目和周围的项目,当用户上下滚动时,它将从点击结果中提取数据。这个想法不是一次加载数千个数据。我需要告诉虚拟控件我在ScoreDoc[]中的特定项目位置,例如ScoreDoc[]中的项目id“99999”位置可能是4000。希望这是有意义的。“塞巴斯蒂安·西格”,谢谢你的评论。我已经编辑了我的帖子,让它更清晰。我需要在ScoreDoc[]中获取find item position,它具有自定义ID属性,其中值可以是“99999”。如果您的结果按分数排序,那么您可能需要的是集合中的item ID(索引)…为什么需要自定义ID?当您再次执行搜索时,您将得到一个结果集,并且您希望从特定docId中获取排序取整项。这就是你想要达到的目标吗?
myCollector.DocumentsByScore