Nest:你应该如何处理 C# 中的亮点
Nest: how are you supposed to deal with the highlights in c#
我正在尝试在索引中搜索 "everything" 搜索词,并显示上下文并突出显示这些词。我返回了一组适当的文档,但无法弄清楚我应该如何处理代码中的突出显示。
此时我只是试图将其转储为文字,下面的代码"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 探索了从搜索中返回的对象。
我正在尝试在索引中搜索 "everything" 搜索词,并显示上下文并突出显示这些词。我返回了一组适当的文档,但无法弄清楚我应该如何处理代码中的突出显示。
此时我只是试图将其转储为文字,下面的代码"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 探索了从搜索中返回的对象。