You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

...

설정

주요 Nuget 의존성 라이브러리

<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를 활용하기위해 NEST가 사용되었으며, 

RDB의 데이터와 검색 인덱스의 데이터 동기화에 드는 개발 비용을 줄이기 위해

ORM이 활용되었습니다.   ORM은 검색 인덱싱을 하는 과정에서만 사용되며,

사용자의 검색 요청은 엘라서틱 서치엔진 API를 직접 사용할 예정이기때문에 이 경우 ORM의 성능은 큰 이슈가 되지 못합니다.

추후 대량의 배치처리시 ORM의 성능 문제가 된다고 하면, 배치성능에 최적화된 ORM 확장 모듈을 사용할수도 있습니다. 

App 설정

appsetting.json
{
  "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

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 설정

Startup.cs
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddElasticsearch(Configuration);
.......


검색 기능 추가

검색 Entity정의

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


검색 Repository for RDB

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


DI를 통한 엘라서틱 서치 클라이언트 사용

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







참고링크:






  • No labels