c# - Nest:你应该如何处理 C# 中的亮点

标签 c# elasticsearch nest

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

在这一点上,我只是想把它转储成一个文字,下面的代码“kinda sorta”有效,但它似乎并没有为每个文档都突出显示,而且感觉不对。我找到了很多关于如何使用高亮显示进行查询的示例,但是我还没有找到任何关于如何显示结果的示例。有什么建议么?谢谢!

    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>";
            }
        }
    }

最佳答案

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

亮点可以在 searchResults.Highlights 中访问(对于所有亮点),或在 IHit<T>.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; }
    }
}

编辑评论: 在此示例中,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 探索了我从搜索中得到的对象。

关于c# - Nest:你应该如何处理 C# 中的亮点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29056578/

相关文章:

c# - C# 和 C++ 之间的同步值?

c# - 有没有办法在 C# 中为泛型类型的特定版本定义隐式转换运算符?

elasticsearch - 在排序之前映射字段的值

elasticsearch - Elasticsearch。按词组过滤\搜索

elasticsearch - 如何检查 ElasticSearch 索引是否存在并准备就绪?

c# - 托管 ASP.NET Core 应用程序

c# - 为 linux 重建 c# 项目

php - 从php存储Logstash日志的最简单方法是什么

docker - Syslog 驱动程序不适用于 docker compose 和 elk stack

c# - 从索引中排除属性