【问题标题】:Nest: how are you supposed to deal with the highlights in c#Nest:你应该如何处理 c# 中的亮点
【发布时间】:2015-03-15 02:22:43
【问题描述】:

我正在尝试在索引中搜索“所有内容”以查找搜索词,并显示上下文并突出显示这些词。我得到了一组适当的文档返回,但无法弄清楚我应该如何处理代码中的突出显示。

此时我只是想将其转储为文字,并且下面的代码“有点像”有效,但它似乎并没有为每个文档突出显示,而且感觉不对。我找到了很多关于如何使用高亮进行查询的示例,但我还没有找到任何关于如何通过显示结果进行任何操作的示例。有什么建议?谢谢!

    var searchResults = client.Search<Document>(s => s.Query(qs => qs.QueryString(q => q.Query(stringsearch))).Highlight(h => h
            .PreTags("<b>")
            .PostTags("</b>")
            .OnFields(
              f => f
                .OnField("*")
                .PreTags("<em>")
                .PostTags("</em>")
            )
        ));

    Literal1.Text = "";

    foreach(var h in searchResults.Hits)
    {
        foreach(var hh in h.Highlights)
        {
            foreach(var hhh in hh.Value.Highlights)
            {
                Literal1.Text += hhh+@"<br>";
            }
        }
    }

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    编辑:下面的解决方案仅在 ElasticSearch 2.x 上测试,而不是 ElasticSearch 5.x/6.x

    可以在searchResults.Highlights(所有精彩片段)或IHit&lt;T&gt;.Highlights 中访问精彩片段。

    这是否符合您想要实现的目标?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using Elasticsearch.Net.ConnectionPool;
    using Nest;
    
    namespace ESTester
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                const string indexName = "testindex";
                var connectionSettings = new ConnectionSettings(new SingleNodeConnectionPool(new Uri("http://127.0.0.1:9200")));
                var client = new ElasticClient(connectionSettings);
    
                var existResponse = client.IndexExists(descriptor => descriptor.Index(indexName));
                if (existResponse.Exists)
                    client.DeleteIndex(descriptor => descriptor.Index(indexName));
    
                // Making sure the refresh interval is low, since it's boring to have to wait for things to catch up
                client.PutTemplate("", descriptor => descriptor.Name("testindex").Template("testindex").Settings(objects => objects.Add("index.refresh_interval", "1s")));
    
                client.CreateIndex(descriptor => descriptor.Index(indexName));
    
                var docs = new List<Document>
                {
                    new Document{Text = "This is the first document" },
                    new Document{Text = "This is the second document" },
                    new Document{Text = "This is the third document" }
                };
    
                var bulkDecsriptor = new BulkDescriptor().IndexMany(docs, (descriptor, document) => descriptor.Index(indexName));
                client.Bulk(bulkDecsriptor);
    
                // Making sure ES has indexed the documents
                Thread.Sleep(TimeSpan.FromSeconds(2));
    
                var searchDescriptor = new SearchDescriptor<Document>()
                    .Index(indexName)
                    .Query(q => q
                        .Match(m => m
                            .OnField(d => d.Text)
                            .Query("the second")))
                    .Highlight(h => h
                        .OnFields(f => f
                            .OnField(d => d.Text)
                            .PreTags("<em>")
                            .PostTags("</em>")));
    
                var result = client.Search<Document>(searchDescriptor);
    
                if (result.Hits.Any())
                {
                    foreach (var hit in result.Hits)
                    {
                        Console.WriteLine("Found match: {0}", hit.Source.Text);
                        if (!hit.Highlights.Any()) continue;
    
                        foreach (var highlight in hit.Highlights.SelectMany(highlight => highlight.Value.Highlights))
                        {
                            Console.WriteLine("Found highlight: {0}", highlight);
                        }
                    }
                }
    
                Console.WriteLine("Press any key to exit!");
                Console.ReadLine();
            }
    
    
        }
    
        internal class Document
        {
            public string Text { get; set; }
        }
    }
    

    为 cmets 编辑: 在此示例中,if(!hit.Highlights.Any()) continue; 没有真正的原因,除了安全之外,但如果您改为执行以下查询,则最终可能会得到没有高亮显示的命中:

        var docs = new List<Document>
        {
            new Document{Text = "This is the first document", Number = 1 },
            new Document{Text = "This is the second document", Number =500 },
            new Document{Text = "This is the third document", Number = 1000 }
        };
    
        var searchDescriptor = new SearchDescriptor<Document>()
            .Index(indexName)
            .Query(q => q
                .Bool(b => b
                    .Should(s1 => s1
                        .Match(m => m
                            .Query("second")
                            .OnField(f => f.Text)),
                        s2 => s2
                            .Range(r =>r
                                .OnField(f => f.Number)
                                .Greater(750)))
                     .MinimumShouldMatch(1)))
            .Highlight(h => h
                .OnFields(f => f
                    .OnField(d => d.Text)
                    .PreTags("<em>")
                    .PostTags("</em>")));
    
      internal class Document
      {
          public string Text { get; set; }
          public int Number { get; set; }
      }
    

    在这种情况下,您可能会在范围查询中获得成功,但不会有任何亮点。

    对于第 2 点,对我来说,我只是在快速观察、对象浏览器和 VS 中的 IntelliSense 中探索了从搜索中返回的对象。

    【讨论】:

    • 谢谢——我会试试这个。一些问题: 1. if (!hit.Highlights.Any()) 继续; ——什么情况下会有爆款,但没有亮点? 2. hit.Highlights.SelectMany(highlight => highlight.Value.Highlights) -- 我怎么知道这个?或者,你是怎么学的?
    • @BillFrench - 这对您的问题有帮助吗?
    猜你喜欢
    • 2012-04-11
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多