如何使用Elasticsearch在.NET应用程序中实现全文搜索

目录

为什么选择Elastic search?

示例应用程序

如何写文件

如何查询文件

获得什么

资源资源


在这个简单的教程中,我将提供一个简单的演示来向Elasticsearch读写文档,并为C#应用程序添加全文本搜索功能。Elasticsearch是一个分布式的开源搜索引擎,可以管理各种数据。了解将其集成到ASP.NET应用程序有多么简单!

为什么选择Elastic search

Elasticsearch是一个分布式的开源搜索引擎,可以管理各种数据。但是,为什么Elasticsearch是全文的最佳解决方案?

我从2009年开始研究全文搜索,当时我必须为数据推荐系统实现搜索算法。这次经历非常有教育意义,但从头开始是一次大屠杀。我第一次获得使用库的机会,我尝试了Apache Lucene来实现全文搜索。随着应用程序架构变得复杂(即,多个服务器需要共享索引数据),Solr提供了可扩展的解决方案。它是一个基于开源API的搜索引擎(基于Lucene)。使用完这些库之后,我使用了Elasticsearch,它现在是市场的领导者。它带有本地免费版本,可在云上使用。它可以从简单的安装扩展到巨大的环境。所以问题是:为什么不呢?

示例应用程序

我在生产以及我的开源headless cms, RawCMS上成功地进行了弹性搜索。为了展示Elasticsearch的工作原理,我创建了一个示例应用程序,其中实现了两个主要功能:

  • 创建索引并向其中添加数据
  • 使用全文查询读取数据

示例代码在GitHub可用。要运行和测试它,只需下载,编译和执行:

dotnet ElasticSearchTest.dll create -f divina_commedia.txt -h http://localhost:9300
> Index created in 30338ms with 14006 element.

dotnet ElasticSearchTest.dll search -i divinacommediatxt 
                                    -h http://localhost:9300 -q "dante AND virgi*"
> Searching for $dante AND virgi*
> "Dante, perché Virgilio se ne vada,
> "Dante, perché Virgilio se ne vada,

控制台应用程序使用该ConsoleLineParser库以人工方式解析输入。因此,我只为动词属性添加了两个类,并在控制台动词和要运行的代码之间添加了映射。

private static void Main(string[] args)
{
    object x = CommandLine.Parser.Default.ParseArguments<CreateOptions, SearchOptions>(args)
      .MapResult(
        (CreateOptions opts) => DoCreate(opts),
        (SearchOptions opts) => DoSearch(opts),
        errs => 1);
}

根据用户输入(搜索或创建)的动词,启动传递参数的相应过程。

如何写文件

写作部分很容易。实际上,对于Elasticsearch,有两种选择。使用低级框架,您可以获得弹性API的包装实现。这有助于避免手动绑定和组合JSON有效负载。但是,如果您想使用数据,NEST是一个不错的选择。NEST是高级框架,如果您是ORM的专家,那么这也就不足为奇了。

您只需要为要保存的文档创建类,并定义如何使用注释保存属性并调用save API

我认为这不太复杂,听起来更像是一个常规例程。这是类定义的代码片段。在此示例中,我每个文档仅使用一个包含一行文本的字段。

public class LogDocument
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string Body { get; set; }
}

下一步是创建索引。在这一步中,我们将索引与类相关联。可以手动完成此操作,指定存储设置或使用自动映射。在我们的示例中,Id字段会自动映射到文档的唯一标识符。

client.Indices.Create(indexName, c => c
                .Map<LogDocument>(m => m
                    .AutoMap<LogDocument>()
                )
            );

最后,我们拥有代码中最愚蠢的部分:写入数据。因为我们要将所有诗句保存到许多文档中(每行一个),所以我们只是进行一次迭代。

string[] lines = File.ReadAllLines(filepath);

int items = 0;
Parallel.ForEach(lines, (line) =>
{
    if (!string.IsNullOrWhiteSpace(line))
    {
        client.CreateDocument<LogDocument>(new LogDocument()
        {
            Body = line.Trim()
        });
        items++;
    }
});

请注意,通过外部系统使用API​​,我们可以使用并行构造来提高性能。

如何查询文件

这部分非常简单而且非常清楚——至少我希望如此。访问文档的基本方法是使用常规流利的LINQ语法。这是基本用法,我更愿意将这个演示集中在文档不太完善的搜索全文数据用例上。

Elastic允许使用原始查询来查找字段数据。为此,您可以使用正确的Search方法重载,配置原始查询:

var searchResponse = client.Search<LogDocument>(s => s
                        .Size(10)
                        .Query(q => q.QueryString(

                            qs => qs.Query(searchStr)
                            .AllowLeadingWildcard(true)
                            )
                        )
                    );

var docs = searchResponse.Documents;

获得什么

Elasticsearch是领先的搜索引擎解决方案。它为应用程序提供了诸如全文搜索或文档索引之类的丰富功能。它可以用作服务或内部部署。无论哪种情况,配置基本用法都非常简单。

NEST框架使我们可以像通过LINQ进行简单数据库存储和访问Elasticsearch一样,这使一切变得非常简单。

对于要让最终用户编写查询的复杂情况,可以使用原始查询并将结果映射到类。

资源资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值