Page History
Tip |
---|
쿼리 DSL은 ORM에 있어서도, 검색엔진을 사용하는 검색 쿼리 사용에 있어서도 복잡한 검색기능을 단순하게 구현 하기위한 좋은 방법중에 하나이며 닷넷 어플리케이션내에서 DSL검색 방식을 사용하기에 적합한 NEST를 선택하였습니다.... |
설정
주요 Nuget 의존성 라이브러리
Code Block |
---|
<PackageReference Include="NEST" Version="7.5.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.3" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" /> |
...
사용자의 검색 요청은 엘라서틱 서치엔진 API를 직접 사용할 예정이기때문에 이 경우 ORM의 성능은 큰 이슈가 되지 못합니다.추후 대량의 배치처리시 ORM의 성능 문제가 된다고 하면, 배치성능에 최적화된 ORM 확장 모듈을 사용할수도 있습니다.
인덱싱이 수정 되고 있을때(풀인덱싱,부분 대량업데이트,실시간성 부분업데이트) 검색(Read)의 성능을 영향받지 않고 -인덱스 데이터의 스왑
RDB보다 훨씬 다양하고 복합적인(풀텍스트,반경검색,검색과 동시에 집계처리등) 순간검색을 위해 인덱스를 효율적으로 설정하고 관리하는 전략이 필요합니다.
다음과 같이 대량 업데이트에 최적화된 Bulk 전략도 필요하게 됩니다.
App 설정
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
{ "Logging": { "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "AppSettings": { "DBConnection": "server=localhost;port=13306;database=search;user=root;password=root;" }, "elasticsearch": { "index": "baseitem", "url": "http://localhost:9200/" } } |
엘라서틱 Config
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Nest; using SearchApi.Entity; namespace SearchApi.Config { public static class ElasticsearchExtensions { public static void AddElasticsearch( this IServiceCollection services, IConfiguration configuration) { var url = configuration["elasticsearch:url"]; var defaultIndex = configuration["elasticsearch:index"]; var settings = new ConnectionSettings(new Uri(url)) .DefaultIndex(defaultIndex) .DefaultMappingFor<SearchGoods>(m => m .PropertyName(p => p.no, "id") ); var client = new ElasticClient(settings); services.AddSingleton<IElasticClient>(client); } } } |
StartUp 설정
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public void ConfigureServices(IServiceCollection services) { services.AddElasticsearch(Configuration); ....... |
검색 기능 추가
검색 Entity정의
Code Block | ||||
---|---|---|---|---|
| ||||
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace SearchApi.Entity { [Table("tbl_search_goods")] public class SearchGoods { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int no { get; set; } [Column("goods_no")] public string goodsNo { get; set; } [Column("name_kr")] public string nameKr { get; set; } [Column("name_en")] public string nameEn { get; set; } public string category1 { get; set; } public string category2 { get; set; } public string category3 { get; set; } public int price { get; set; } [Column("view_cnt")] public int viewCnt { get; set; } [Column("sale_cnt")] public int saleCnt { get; set; } public string terms { get; set; } public string tags { get; set; } [Column("url_pc")] public string urlPc { get; set; } [Column("url_mobile")] public string urlMobile { get; set; } [Column("image_url1")] public string imageUrl1 { get; set; } [Column("image_url2")] public string imageUrl2 { get; set; } } } |
검색데이터의 정의는 익숙한 RDB 모델(엔티티)로부터 먼저 시작하여
검색엔진의 문서의 검색 속성을 일치화할것입니다.
검색 Repository for RDB
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
using System; using Microsoft.EntityFrameworkCore; using SearchApi.Config; using SearchApi.Entity; namespace SearchApi.Repositories { public class SearchRepository : DbContext { private const string database = "search"; private readonly AppSettings appSettings; private readonly bool isEncript; public string DebugConString { get; set; } public DbSet<SearchGoods> searchGoods { get; set; } public SearchRepository(DbContextOptions<SearchRepository> options, AppSettings _appSettings) : base(options) { appSettings = _appSettings; if (!appSettings.DBConnection.Contains("localhost")) { isEncript = true; } } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { string dbOption = ""; string dbConnectionString = string.Empty; if (isEncript) { throw new NotImplementedException("암호화 모듈을 적용하시오~"); } else { dbConnectionString = appSettings.DBConnection + $"database={database};" + dbOption; } optionsBuilder.UseMySql(dbConnectionString); } } } } |
검색 데이터의 원본은 RDB 이며 ORM을 활용합니다.
닷넷코어에서 Entity설정은 다음을 추가참고합니다.
Link : https://docs.microsoft.com/en-us/ef/core/
DI를 통한 엘라서틱 서치 클라이언트 사용
Code Block | ||||
---|---|---|---|---|
| ||||
using Microsoft.AspNetCore.Mvc; using Nest; namespace SearchApi.Controllers { [Route("api/[controller]")] [ApiController] public class TestController : ControllerBase { private readonly IElasticClient _elasticClient; public TestController(IElasticClient elasticClient) { _elasticClient = elasticClient; } } } |
IElasticClient 객체가 실제 엘라서틱서버 연결설정이 완료되어
사용준비가 되면 기본 설정이 완료 되었으며
다음장에서는 최초 검색데이터를 인덱싱→인덱스 한 상태에서
기본적인 검색 기능을 구현하는것에대해 알아 보겠습니다.
참고링크:
- https://miroslavpopovic.com/posts/2018/07/elasticsearch-with-aspnet-core-and-docker
- https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/writing-analyzers.html
- https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/testing-analyzers.html
...