Page History
...
단일 DB에서 다양한 검색수행
반경검색/FullText검색및 Vector검색을 단일DB에서 효율적으로 검색해낼수 Vector검색등 고급 검색기능을 단일DB만사용해 검색할수 있습니다.
| Code Block | ||
|---|---|---|
| ||
using ActorLib.Persistent.Model; using Raven.Client.Documents; using Raven.Client.Documents.Indexes.Vector; using Raven.Client.Documents.Linq; namespace ActorLib.Persistent; public class TravelReviewRepository { private readonly IDocumentStore _store; public TravelReviewRepository(IDocumentStore store) { _store = store ?? throw new ArgumentNullException(nameof(store)); } public void AddReview(TravelReview review) { using (var session = _store.OpenSession()) { session.Store(review); session.SaveChanges(); } } public List<TravelReview> SearchReviews(string keyword, double latitude, double longitude, double radiusKm, string category = null) { using (var session = _store.OpenSession()) { // 명시적으로 변수로 선언 var keywordValue = keyword; var categoryValue = category; IRavenQueryable<TravelReview> query = session.Query<TravelReview>(); if (!string.IsNullOrEmpty(keywordValue)) { query = query.Search(r => r.Content, keywordValue); // FullText검색제목 검색 추가 } if (!string.IsNullOrEmpty(categoryValue)) { query = query.Where(r => r.Category == categoryValue); // 제목 일반적인검색 필터추가 } // RavenDB에서 서버 측 필터링 후 클라이언트 측에서 반경 필터링 var results = query.ToList(); return results.Where(r => 6371 * Math.Acos( Math.Cos(DegToRad(latitude)) * Math.Cos(DegToRad(r.Latitude)) * Math.Cos(DegToRad(r.Longitude) - DegToRad(longitude)) + Math.Sin(DegToRad(latitude)) * Math.Sin(DegToRad(r.Latitude)) ) <= radiusKm).ToList(); } } public List<TravelReview> SearchReviewsByRadius(double latitude, double longitude, double radiusKm) { using (var session = _store.OpenSession()) { return session.Query<TravelReview>() .Spatial( r => r.Point(x => x.Latitude, x => x.Longitude), criteria => criteria.WithinRadius(radiusKm, latitude, longitude)) .ToList(); } } public List<TravelReview> SearchReviewsByVector(float[] queryVectorvector, int topN = 5) { using (var session = _store.OpenSession()) { var results = session.AdvancedQuery<TravelReview>() .RawQuery<TravelReview>VectorSearch( @"from index 'TravelReview_Index'field => field.WithEmbedding(x => x.TagsEmbeddedAsSingle, VectorEmbeddingType.Single), queryVector where TitleVector vector $queryVector=> queryVector.ByEmbedding(new RavenVector<float>(vector)), order by score() desc0.85f, limit $topN"topN) .AddParameter("queryVector", queryVectorCustomize(x => x.WaitForNonStaleResults()) .AddParameter("topN", 10) ToList(); .ToList(); return results; } } private double DegToRad(double degrees) { return degrees * (Math.PI / 180); } } |
- 데이터엔지니어팀이 있다고하면 특화된 전문화 DB를 각각 이용할수도 있겠지만 고성능 벌크처리/분산(Shard)저장을 포함 오늘날 유행을 타고 있는 AIRag를 이용하기위한 Vector검색 까지 Vector검색과 같이 특수한 검색기능은 RawQuery를 사용해야하며 나머지는 Linq를 이용할수 있습니다.
- 추가참고 링크
- https://ravendb.net/docs/article-page/7.0/csharp/ai-integration/vector-search/vector-search-using-dynamic-query
- https://ravendb.net/docs/article-page/7.0/csharp/sharding/overview
- https://ravendb.net/docs/article-page/7.0/csharp/client-api/bulk-insert/how-to-work-with-bulk-insert-operation
- https://ravendb.net/why-ravendb
- Raven전용 네이티브 쿼리가 익숙하지않아 아직 성공은 못함 ( raven 6.x부터 지원 )
CQRS로의 여정
CRUD또는 검색기능만 이용하려고 RavenDB를 조사한것은 아니며 Akka.net의 Persist기능이 제공하는 CQRS장치와 연동이됨으로
...

