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