Luận văn thạc sĩ ứng dụng mã nguồn mở elasticsearch vào hệ thống tìm kiếm danh bạ y tế hiệu quả

98 3 0
Luận văn thạc sĩ ứng dụng mã nguồn mở elasticsearch vào hệ thống tìm kiếm danh bạ y tế hiệu quả

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

NGUYỄN VĂN THÌN BỘ GIÁO DỤC VÀ ĐÀO TẠO VIỆN HÀN LÂM KHOA HỌC VÀ CÔNG NGHỆ VN HỌC VIỆN KHOA HỌC VÀ CƠNG NGHỆ Nguyễn Văn Thìn HỆ THỐNG THÔNG TIN ỨNG DỤNG MÃ NGUỒN MỞ ELASTICSEARCH VÀO HỆ THỐNG TÌM KIẾM DANH BẠ Y TẾ HIỆU QUẢ LUẬN VĂN THẠC SĨ NGÀNH MÁY TÍNH 2021 Thành phố Hồ Chí Minh - 2021 n BỘ GIÁO DỤC VÀ ĐÀO TẠO VIỆN HÀN LÂM KHOA HỌC VÀ CÔNG NGHỆ VN HỌC VIỆN KHOA HỌC VÀ CƠNG NGHỆ Nguyễn Văn Thìn ỨNG DỤNG MÃ NGUỒN MỞ ELASTICSEARCH VÀO HỆ THỐNG TÌM KIẾM DANH BẠ Y TẾ HIỆU QUẢ Chuyên ngành : Hệ Thống Thông Tin Mã số : 8480104 LUẬN VĂN THẠC SĨ NGÀNH MÁY TÍNH NGƯỜI HƯỚNG DẪN KHOA HỌC: TS TRẦN TRỌNG TỒN Thành phố Hồ Chí Minh – 2021 n i LỜI CAM ĐOAN Tôi cam đoan luận văn “Ứng dụng mã nguồn mở ElasticSearch vào hệ thống tìm kiếm danh bạ y tế hiệu quả” cơng trình nghiên cứu riêng tơi hướng dẫn Thầy TS Trần Trọng Toàn Sự gần gũi nhiệt tình hướng dẫn thầy nguồn động lực lớn suốt thời gian thực Các số liệu, kết nêu luận văn trung thực chưa công bố cơng trình khác Thành phố Hồ Chí Minh, ngày tháng năm 2021 Học viên thực Nguyễn Văn Thìn n ii LỜI CẢM ƠN Tơi xin gửi lời cảm ơn sâu sắc đến thầy TS Trần Trọng Tồn tận tình hướng dẫn giúp đỡ tơi suốt q trình thực luận văn Cảm ơn quý thầy cô Khoa Công Nghệ Thông Tin Viễn Thông, Thầy Cô Học Viện Khoa học Công Nghệ, quý thầy cô tham gia giảng dạy truyền đạt kiến thức cho thân tơi suốt khóa học 2018 – 2020 Cho phép gửi lời cảm ơn tới bạn, đồng nghiệp thường xuyên quan tâm, giúp đỡ, chia kinh nghiệm suốt thời gian học tập, nghiên cứu Học viện suốt trình thực luận văn Tôi xin bày tỏ biết ơn sâu sắc đến cha, mẹ, vợ, người thân gia đình ln bên tơi, động viên, dành cho tơi tốt đẹp suốt q trình thực luận văn Cuối xin chân thành cảm ơn Công ty Cổ phần MediHub tạo điều kiện giúp thực tốt luận văn Trân trọng cảm ơn! n iii MỤC LỤC LỜI CAM ĐOAN i LỜI CẢM ƠN .ii MỤC LỤC iii DANH MỤC VIẾT TẮT iv DANH MỤC CÁC BẢNG vi DANH MỤC CÁC HÌNH MINH HỌA vii MỞ ĐẦU CHƯƠNG - TỔNG QUAN VỀ HỆ THỐNG TÌM KIẾM THƠNG TIN 1.1 Khái niệm tìm kiếm thơng tin 1.2 Khái niệm hệ thống tìm kiếm thơng tin 1.2.1 Khái niệm hệ thống tìm kiếm thơng tin 1.2.2 Các phận cấu thành hệ thống tìm kiếm thơng tin CHƯƠNG - GIỚI THIỆU BÀI TOÁN VÀ LỰA CHỌN CÔNG NGHỆ 2.1 Giới thiệu toán 2.2 Phương pháp giải 2.3 Tổng quan ElasticSearch 10 2.3.1 Khái niệm ElasticSearch 10 2.3.2 Các khái niệm cần biết ElasticSearch 13 2.3.3 Analyzers mơ hình truy hồi thơng tin ElasticSearch 21 2.3.4 Query DSL (domain- Specific Language) ElasticSearch 29 2.3.5 Mơ hình truy hồi thơng tin ElasticSearch 36 CHƯƠNG THỰC NGHIỆM XÂY DỰNG WEBSITE TÌM KIẾM DANH BẠ Y TẾ 45 3.1 Phân tích 45 3.2 Thiết kế 46 3.3 Cài đặt 55 3.4 Giao diện 55 n iv 3.4.1 Giao diện cho người sử dụng 55 3.4.2 Giao diện cho người quản trị 64 3.5 Đánh giá thử nghiệm 66 3.5.1 Mơ hình kiến trúc ứng dụng thử nghiệm 66 3.5.2 Kịch kết 67 3.5.3 Đánh giá kết nghiên cứu 70 CHƯƠNG KẾT LUẬN 72 DANH MỤC TÀI LIỆU THAM KHẢO 73 n v DANH MỤC CÁC THUẬT NGỮ, CHỮ VIẾT TẮT CNTT Công nghệ thông tin CSDL Cơ sở liệu Server Máy chủ Document Tài liệu Index Chỉ mục ES ElasticSearch EHR Hồ sơ sức khỏe điện tử IR Information Retrieval Shard Phân đoạn Query Truy vấn DSL domain- Specific Language URL Địa website Term Từ khóa tìm kiếm Boost Tăng cường API Application Programming Interface RESTful API Một tiêu chuẩn việc thiết kế API row Dòng table bảng Unicast thuật ngữ sử dụng mạng máy tính để mơ tả cách thức truyền tin gửi từ điểm đến điểm khác link Liên kết n vi DANH MỤC CÁC BẢNG Bảng 1: Số liệu mapping từ khóa 53 Bảng 2: Kịch tìm kiếm 68 n vii DANH MỤC CÁC HÌNH MINH HỌA Hình 1: Lịch sử hình thành công ty ElasticSearch 10 Hình 2: Các tập đồn sử dụng ElasticSearch 11 Hình 3: Các đối thủ ElasticSearch 11 Hình 4: Bảng so sánh dịch vụ 12 Hình 5: Hệ thống phân tán ElasticSearch 13 Hình 6: Các khái niệm cần biết ElasticSearch 13 Hình 7: Index ElasticSearch 14 Hình 8: Sharding Index 15 Hình 9: Primary Shard Replica Shard 15 Hình 10: trình chuyển liệu 17 Hình 11: Cluster ElasticSearch 18 Hình 12: Ví dụ sơ đồ sở liệu Mapping 19 Hình 13: Analyzer ElasticSearch 21 Hình 14: Kết tìm kiếm Match all query 30 Hình 15: Kết Match query 30 Hình 16: Kết Match query thêm and 31 Hình 17: Kết Match phrase query 31 Hình 18: Kết Match Phrase Prefix Query 32 Hình 19: Kết Multi Match Query 32 Hình 20: Query có parameters 33 Hình 21: Query với format ngày 33 Hình 22: Wildcard Query 34 Hình 23: Bool Query 34 Hình 24: Fuzzy Query 36 Hình 25: B25M 38 Hình 26: BM25 tiệm cận 40 Hình 27: BM25 với độ dài trung bình 41 Hình 28: Mơ hình tìm kiếm văn tiếng Việt 46 Hình 29: lược đồ Analyzer 47 Hình 30: lược đồ sở liệu Danh bạ y tế 53 Hình 31: Mơ hình cho người sử dụng 54 Hình 32: giao diện gợi ý nhập từ khóa 56 Hình 33: kết tìm kiếm có dấu 56 Hình 34: kết tìm kiếm tiếng Việt không dấu 57 n viii Hình 35: Kết tìm kiếm 58 Hình 36: Kết theo định vị 59 Hình 37: Tìm kiếm theo chuyên khoa 61 Hình 38 thông tin chi tiết 61 Hình 39: thơng tin đồ theo địa Profile 62 Hình 40: nút lưu profile 62 Hình 41: hỏi đáp 63 Hình 42: Thơng tin lưu, thích 63 Hình 43: Trang quản trị Admin 64 Hình 44: Cập nhật liệu 65 Hình 45: Quản trị tài khoản 65 Hình 46 Kiến trúc Mơ hình thử nghiệm 67 n 74 [11] Christopher D.Manning Prabhakar Raghavan Hinrich Schütze (2009), Introduction to Infomation Retrieval, Cambridgec University Press Cambridge, England [12] https://seongon.com/seo/kien-thuc-seo/seach-engine.html, access date: Oct 10, 2020 [13] http://www.searchenginehistory.com/, access date: Dec 10, 2020 [14] Duy Đỗ “Vietnamese Analysis Plugin for Elasticsearch”, https://github.com/duydo/elasticsearch-analysis-vietnamese, access date: Dec 27, 2020 [15] https://github.com/phuonglh/vn.vitk, access date: Dec 20, 2020 [16] Brian D Sloan (2017), ES-ESA: An Information Retrieval Prototype Using Explicit Semantic Analysis and Elasticsearch, The Graduate Center, City University of New York [17] Clinton Gormley & Zachary Tong (2015), Elasticsearch: The Denitive Guide, Printed in the United States of America, Published by O’Reilly Media, Inc , 1005 Gravenstein Highway North, Sebastopol, CA 95472 [18] Elastic Search, https://www.elastic.co/guide/en/elasticsearch/reference/7.x/index.html [19] https://pluralsight.com/courses/elasticsearch-indexing-data [20] https://en.wikipedia.org/wiki/Levenshtein_distance, access date: Dec 20, 2020 [21] https://www.compose.com/articles/how-scoring-works-in-elasticsearch/, access date: Dec 30, 2020 [22] Vô danh (2020), Thuật toán đánh giá _score ElasticSearch, https://viblo.asia/p/thuat-toan-danh-gia-score-trong-elasticsearchOeVKBY7y5kW , truy cập ngày: 08/10/2020 [23] BM25 The Next Generation of Lucene Relevance (2015), https://opensourceconnections.com/blog/2015/10/16/bm25-the-nextgeneration-of-lucene-relevation, access date: Oct 10, 2020 [24] S E Robertson and H Zaragoza 2009 “The Probabilistic Relevance Framework: BM25 and Beyond” Foundations and Trends in Information Retrieval 3(4): 333-389 [25] William R Hersh, Chapter 14: Information Retrieval for Healthcare, Department of Medical Informatics & Clinical Epidemiology (DMICE) Oregon Health & Science University Portland n 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 PHỤ LỤC // Tạo interface cho method public interface IHealthcareElastichSearchService { Task GetDataSearch(string keyword, int pageSize, int page, int score); Task GetDataSearchGeo(double lat, double ln, GeoDistanceType type, string distance, int pageSize, int page, string keyword); Task GetDataSearchGeo(double lat, double ln, GeoDistanceType type, string distance, int pageSize, int page); Task GetDataSuggestion(string keyword, int page, int pageSize); Task GetDataSuggestionWithIcu(string term, int page, int pageSize); Task InsertDataHealthcare(HealthCareModel model); void UpdateDataHealthcare(HealthCareModel model); void DeleteDataHealthcare(HealthCareModel model); HealthCareModel GetDataHealthcarebyId(string id); Task UpdateHealthcare(string id); Task GetDataSearchWithSpecialist(string specialist, int pageSize, int page, float score); } // Implement Code kế thừa từ interface public class HealthcareElastichSearchService : IHealthcareElastichSearchService { private readonly IElasticClient _elasticClient; private readonly string _index; public HealthcareElastichSearchService(IElasticClient elasticClient, IConfiguration configuration) { _elasticClient = elasticClient; _index = configuration["elasticsearch:index"]; } // Lấy liệu từ document theo Id public HealthCareModel GetDataHealthcarebyId(string id) { n 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 var response = _elasticClient.Get(id, u => u.Index(_index)).Source; return response; } ệu // Tìm kiếm liệu theo từ khóa phân trang, dùng stopwatch để kiểm tra thời gian lấy li public async Task GetDataSearch(string keyword, int pageSize, int page, int score) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var response = await _elasticClient.SearchAsync(s => s Query(q => q Match(m => m Field(f => f.KeyWords) Query(keyword) ) ).From((page - 1) * pageSize).Size(pageSize) Sort(s => s.Descending(SortSpecialField.Score)).MinScore(score) ).ConfigureAwait(false); long total = response.HitsMetadata.Total.Value; var rs = new PaginatedList(response.Documents.ToList(), total, page, pageSize); return rs; } // Tìm kiếm theo chuyên khoa public async Task GetDataSearchWithSpecialist(string specialist, int pageSize, int page, float score) { var response = await _elasticClient.SearchAsync( s => s.Query(q => q.QueryString(d => d.Query(specialist).Fields(f => f.Fields(f => f.KeyWords)))).Sort(s => s.Descending(SortSpecialField.Score)) From((page - 1) * pageSize).MinScore(score) Size(pageSize)).ConfigureAwait(false); var rs = new PaginatedList(response.Documents.ToList(), response.Documents.Count, page, pageSize); return rs; } // Tìm kiếm theo chuyên khoa từ khóa public async Task GetDataSpecialistSearch(string specialist, string keyword, int pageSize, int page, int score) { var response = await _elasticClient.SearchAsync( s => s.Query(q => q.QueryString(d => d.Query(keyword))).Sort(s => s.Descending(SortSpecialField.Score)) From((page - 1) * pageSize) Size(pageSize)).ConfigureAwait(false); n 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 var rs = new PaginatedList(response.Documents.ToList(), response.Documents.Count, page, pageSize); return rs; } // Tìm kiếm theo tọa độ public async Task GetDataSearchGeo(double lat, double ln, GeoDistanceType type, string distance, int pageSize, int page) { var geo = await _elasticClient.SearchAsync(s => s.From(0).Size(pageSize)//.ScriptFields(sf => sf.ScriptField("distance", d => d.Source("if(doc['geo'].size(){doc['geo'].arcDistance(" + lat + "," + ln + ")}"))) Query(q => q GeoDistance(g => g Boost(1.1) Name("named_query") Field(p => p.GeoLocation) DistanceType(type) Location(lat, ln) Distance(distance) ValidationMethod(GeoValidationMethod.IgnoreMalformed) )) ); return new PaginatedList(geo.Documents.ToList(), geo.Documents.Count, page, pageSize); } // Tìm kiếm theo tọa độ từ khóa public async Task GetDataSearchGeo(double lat, double ln, GeoDistanceType type, string distance, int pageSize, int page, string keyword) { var geo = await _elasticClient.SearchAsync(s => s.From(0).Size(pageSize) Query(q => q Match(m => m Field(f => f.KeyWords) Query(keyword) ) ).MinScore(5) PostFilter(q => q GeoDistance(g => g Boost(1.1) Name("named_query") Field(p => p.GeoLocation) DistanceType(type) Location(lat, ln) n 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 Distance(distance) ValidationMethod(GeoValidationMethod.IgnoreMalformed) ) ) ); return new PaginatedList(geo.Documents.ToList(), geo.Documents.Count, page, pageSize); } // lấy liệu gợi ý cho từ khóa public async Task GetDataSuggestion(string term, int page, int pageSize) { var response = await _elasticClient.SearchAsync(s => s Query(q => q Match(m => m Field(f => f.KeyWords) Query(term).Fuzziness(Fuzziness.Auto) ) ).From((page - 1) * pageSize).Size(pageSize).Sort(s => s.Descending(SortSpecialField.Score)) ).ConfigureAwait(false); var rs = response.Documents.Select(x => $" {x.Name} -{x.Specialist}"); return rs.ToList(); } // Lấy liệu gợi ý với từ khóa khơng dấu public async Task GetDataSuggestionWithIcu(string term, int page, int pageSize) { var response = await _elasticClient.SearchAsync(s => s Query(q => q Match(m => m Field(f => f.KeyWords) Query(term).Analyzer("my_analyzer").Fuzziness(F uzziness.Auto) ) ).From((page - 1) * pageSize).Size(pageSize).Sort(s => s.Descending(SortSpecialField.Score)).MinScore(0.4) ).ConfigureAwait(false); var rs = response.Documents.Select(x => $" {x.Name} -{x.Specialist}"); return rs.ToList(); } // Đẩy liệu lên ElasticSearch public async Task InsertDataHealthcare(HealthCareModel model) { _ = await _elasticClient.IndexDocumentAsync(model); } // Cập nhật lại liệu ElasticSearch n 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 public void UpdateDataHealthcare(HealthCareModel model) { _elasticClient.Delete(model.Id, u => u.Index(_index)); _elasticClient.IndexDocument(model); } // Cập nhật lại liệu ElasticSearch với chế acsync public async Task UpdateHealthcare(HealthCareModel model) { var response = await _elasticClient.UpdateAsync(model.Id, u => u.Index(_index).Doc(model)); } // Cập nhật lại liệu View từ người dùng public async Task UpdateHealthcare(string id) { var update = GetDataHealthcarebyId(id); if (update != null) { update.Viewed += 1; await _elasticClient.UpdateAsync(update.Id, u => u.Index(_index).Doc(update)); } } } // Controller xử lý route url public class HealthcareController : Controller { private readonly IHealthcareElastichSearchService _healthcareElastichSearchService; private readonly IDoctorRepository _doctorRepository; private readonly IHospitalRepository _hospitalRepository; private readonly ILogger _logger; public HealthcareController( IHealthcareElastichSearchService healthcareElastichSearchService, IDoctorRepository doctorRepository, IHospitalRepository hospitalRepository, ILogger logger) { _healthcareElastichSearchService = healthcareElastichSearchService; _doctorRepository = doctorRepository; _hospitalRepository = hospitalRepository; _logger = logger; } // Trang chủ public IActionResult Index() { return View(); n 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 } // Trang tìm kiếm [HttpGet("healthcare/Search")] public async Task Search(int? page) { string term = HttpContext.Request.Query["term"].ToString(); ; page = page ?? 1; var rs = await _healthcareElastichSearchService.GetDataSearch(term, 100, page.Value, 10); ViewBag.term = term; return View(rs); } // Trang gợi ý liệu với vị trí gần tơi [HttpGet("healthcare/FindNearby")] public IActionResult FindNearby(double lat, double ln) { return View(); } // Trang tìm kiếm từ khóa theo độ tọa [HttpGet("healthcare/FindNearme/{lat}/{ln}")] public async Task FindNearme(double lat, double ln) { var keyword = HttpContext.Request.Query["keyword"]; if (lat != && ln != 0) { PaginatedList rs = null; if (string.IsNullOrEmpty(keyword)) { rs = await _healthcareElastichSearchService.GetDataSearchGeo(lat, ln, Nest.GeoDistanceType.Arc, "3000m", 50, 1); } else { rs = await _healthcareElastichSearchService.GetDataSearchGeo(lat, ln, Nest.GeoDistanceType.Arc, "3000m", 100, 1, keyword); } ViewBag.Lat = lat; ViewBag.Ln = ln; return View(rs); } return View(); } // Tìm kiếm theo chuyên khoa [HttpGet("healthcare/FindbySpecialist")] n 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 public async Task FindbySpecialist(string specialist) { ViewBag.Selected = specialist; var rs = await _healthcareElastichSearchService.GetDataSearchWithSpecialist(specialist, 30, 1, 5); return View(rs); } // Get địa [HttpGet("healthcare/GetAddress")] public JsonResult GetAddress(double lat, double ln) { var rs = CommonUtils.GetAddress(lat, ln); var displayname = rs.display_name.Replace(", Long Điền, 711001, Việt Nam", ""); return Json(new { success = true, message = "Thành công", data = $"{displayname}" }); } // Gợi ý từ khóa [HttpGet("healthcare/SearchSuggest")] public async Task SearchSuggest() { string term = HttpContext.Request.Query["term"].ToString(); var rs = await _healthcareElastichSearchService.GetDataSuggestion(term, 1, 20); return Ok(rs); } // Trang profile Bác sĩ [HttpGet("healthcare/doctorprofile/{slug}")] public async Task DoctorProfile(string slug) { var doctor = _doctorRepository.GetAllData().Where(x => x.Slug.Equals(slug)) Include(i => i.Questions).FirstOrDefault(); await _healthcareElastichSearchService.UpdateHealthcare(doctor.DocId); doctor.Viewed += 1; _doctorRepository.Update(doctor); return View(doctor); } // Trrang profile phòng khám bệnh viện [HttpGet("healthcare/pospitalorclinic/{slug}")] public async Task HospitalOrClinicProfile(string slug) n 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 { var data = _hospitalRepository.GetAllData().Where(x => x.Slug.Equals(slug)).FirstOrDefault(); await _healthcareElastichSearchService.UpdateHealthcare(data.DocId); data.Viewed += 1; _hospitalRepository.Update(data); return View(data); } // Load liệu thô từ MSSQL lên ElasticSearch [Authorize] [HttpGet("healthcare/InputData")] public async Task RunDataIndex() { // Doctor var rs = _doctorRepository.GetAll().Where(x => x.Lon > && x.Lat > 0).ToList().Select(x => new HealthCareModel { Id = x.DocId, Name = x.Name ?? "", Address = x.OfficeAddress, KeyWords = $"{x.Name} , {x.Specialist}, {x.Services}", Specialist = x.Specialist ?? "", TypeHealthCare = HealthCareEnum.Doctor.GetHashCode(), PhoneNumber = x.PhoneNumber ?? "", Viewed = x.Viewed, WorkPlace = x.OfficeAddress, GeoLocation = new GeoLocation(x.Lat, x.Lon), Slug = x.Slug, // Description = x.Services ?? "", }).Where(x => !string.IsNullOrEmpty(x.Address)).ToList(); foreach (var doc in rs) { try { await _healthcareElastichSearchService.InsertDataHealthcare(doc); } catch (Exception ex) { var x = ex.ToString(); _logger.LogError(ex, ex.Message); } } var host = _hospitalRepository.GetAll().Where(x => x.Lon > && x.Lat > 0).ToList().Select(x => new HealthCareModel { Id = x.DocId, Name = x.FullName ?? "", Address = x.OfficeAddress, KeyWords = $"{x.FullName} , {x.Specialist}, {x.Services}", n 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 Specialist = x.Specialist ?? "", TypeHealthCare = x.Type == "benh-vien" ? HealthCareEnum.Hospital.GetHashCode() : HealthCareEnum.Clinic.GetHashCode(), PhoneNumber = x.PhoneNumber ?? "", Viewed = x.Viewed, WorkPlace = x.OfficeAddress, GeoLocation = new GeoLocation(x.Lat, x.Lon), Slug = x.Slug, // Description = x.Services ?? "", }).Where(x => !string.IsNullOrEmpty(x.Address)).ToList(); foreach (var r in host) { try { await _healthcareElastichSearchService.InsertDataHealthcare(r); } catch (Exception ex) { var x = ex.ToString(); _logger.LogError(ex, ex.Message); } } return View(); } // Xử lý update liệu [HttpGet("healthcare/UpdateData")] public async Task UpdateData() { var host = _hospitalRepository.GetAll().Where(x => x.Lon > && x.Lat > 0).ToList().Select(x => new HealthCareModel { Id = x.DocId, Name = x.FullName ?? "", Address = x.OfficeAddress, KeyWords = $"{x.FullName} , {x.Specialist}, {x.Services}", Specialist = x.Specialist ?? "", TypeHealthCare = x.Type == "benh-vien" ? HealthCareEnum.Hospital.GetHashCode() : HealthCareEnum.Clinic.GetHashCode(), PhoneNumber = x.PhoneNumber ?? "", WorkPlace = x.OfficeAddress, GeoLocation = new GeoLocation(x.Lat, x.Lon), Slug = x.Slug, // Description = x.Services ?? "", }).Where(x => !string.IsNullOrEmpty(x.Address)).ToList(); foreach (var r in host) { try n 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 { _healthcareElastichSearchService.UpdateDataHealthcare(r); } catch (Exception ex) { var x = ex.ToString(); _logger.LogError(ex, ex.Message); } } return View(); } // Hàm xử lý tính Like Bác sĩ [HttpGet("healthcare/likedoctor/{slug}")] public IActionResult LikeDoctor(string slug) { if (!string.IsNullOrEmpty(slug)) { var doctor = _doctorRepository.GetByFiler(f => f.Slug == slug).FirstOrDefault(); var userId = string.Empty; bool isCookie = false; if (User.Identity.IsAuthenticated) { userId = User.FindFirst(ClaimTypes.Name)?.Value; } else { //var user = User.Identity.Name; var cookie = HttpContext.Request.Cookies["x-header-userdata"]; if (string.IsNullOrEmpty(cookie)) { cookie = Guid.NewGuid().ToString(); Response.Cookies.Append("x-header-userdata", cookie, new CookieOptions() { Path = "/" } ); userId = cookie; } isCookie = true; } var check = _doctorRepository.GetUserLikeDoctor(userId, doctor.Id); if (check == null) { doctor.Liked = doctor.Liked ?? + 1; _doctorRepository.InsertLike(userId, doctor.Id, isCookie); _doctorRepository.SaveChanges(); n 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 return Json(new { Status = true, Message = $"Cảm ơn bạn đánh giá hài lòng bác sĩ {doctor.Name}" }); } return Json(new { Status = false, Message = $"Bạn đánh giá hài lòng bác sĩ {doctor.Name} rồi." }); } return Json(new { Status = false, Message = "Thông tin không hợp lệ" }); } // Hàm xử ký tính lưu Bác sĩ [HttpGet("healthcare/savedoctor/{slug}")] public IActionResult SaveDoctor(string slug) { if (!string.IsNullOrEmpty(slug)) { slug = slug.Replace("{", "").Replace("}", ""); var doctor = _doctorRepository.GetByFiler(f => f.Slug == slug).FirstOrDefault(); var userId = string.Empty; if (User.Identity.IsAuthenticated) { userId = User.FindFirst(ClaimTypes.Name)?.Value; } else { return RedirectToAction("login", "Accounts", new { returnUrl = $"/healthcare/savedoctor/{slug}" }); } var check = _doctorRepository.GetUserSaveDoctor(userId, doctor.Id); if (check == null) { _doctorRepository.InsertSave(userId, doctor.Id); _doctorRepository.SaveChanges(); } return RedirectToAction("MyBookmark", "Accounts"); } return Json(new { Status = false, Message = "Thông tin không hợp lệ" }); } // Hàm xử lý tính like phòng khám bệnh viện [HttpGet("healthcare/likehospital/{slug}")] public IActionResult LikeHospital(string slug) { if (!string.IsNullOrEmpty(slug)) { var hospital = _hospitalRepository.GetByFiler(f => f.Slug == slug).FirstOrDefault(); var userId = string.Empty; bool isCookie = false; n 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 if (User.Identity.IsAuthenticated) { userId = User.FindFirst(ClaimTypes.Name)?.Value; } else { //var user = User.Identity.Name; var cookie = HttpContext.Request.Cookies["x-header-userdata"]; if (string.IsNullOrEmpty(cookie)) { cookie = Guid.NewGuid().ToString(); Response.Cookies.Append("x-header-userdata", cookie, new CookieOptions() { Path = "/" } ); userId = cookie; } isCookie = true; } var check = _hospitalRepository.GetUserLikeHospital(userId, hospital.Id); if (check == null) { hospital.Liked = hospital.Liked ?? + 1; _hospitalRepository.InsertLike(userId, hospital.Id, isCookie); _hospitalRepository.SaveChanges(); return Json(new { Status = true, Message = $"Cảm ơn bạn đánh giá hài lòng {hospital.FullName}" }); } return Json(new { Status = false, Message = $"Bạn đánh giá hài lòng {hospital.FullName} rồi." }); } return Json(new { Status = false, Message = "Thông tin không hợp lệ" }); } // Hàm xử lý tính lưu phịng khám bệnh viện [HttpGet("healthcare/savehospital/{slug}")] public IActionResult SaveHospital(string slug) { if (!string.IsNullOrEmpty(slug)) { slug = slug.Replace("{", "").Replace("}", ""); var hospital = _hospitalRepository.GetByFiler(f => f.Slug == slug).FirstOrDefault(); var userId = string.Empty; if (User.Identity.IsAuthenticated) { userId = User.FindFirst(ClaimTypes.Name)?.Value; n 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 } else { return RedirectToAction("login", "Accounts", new { returnUrl = $"/healthcare/savehospital/{slug}" }); } var check = _hospitalRepository.GetUserSaveHospital(userId, hospital.Id); if (check == null) { _hospitalRepository.InsertSave(userId, hospital.Id); _hospitalRepository.SaveChanges(); } return RedirectToAction("MyBookmark", "Accounts"); } return Json(new { Status = false, Message = "Thông tin không hợp lệ" }); } } // Controller cho Admin quản lý thêm Bác sĩ public class DoctorsController : Controller { private readonly IDoctorRepository _doctorRepository; private readonly ILogger _logger; private readonly IMapper _mapper; private readonly int _pageSize = 10; public DoctorsController(IDoctorRepository doctorRepository, IMapper mapper, ILogger logger) { _doctorRepository = doctorRepository; _logger = logger; _mapper = mapper; } [HttpGet("doctors/getall")] public async Task Index(int? page) { var filter = HttpContext.Request.Query["search"]; if (page == null) { page = 1; } var rs = _doctorRepository.GetAllData(); if (!string.IsNullOrEmpty(filter.ToString())) { ViewData["CurrentFilter"] = filter.ToString(); rs = rs.Where(x =>x.Name.Contains(filter.ToString())).AsNoTracking(); } return View(await PaginatedList.CreateAsync(rs.OrderByDescending(x => x.CreatedDate), page ?? 1, _pageSize)); n 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 } [HttpGet("doctors/AddDoctor")] public IActionResult AddDoctor() { return View(); } [HttpPost("doctors/AddDoctor")] public IActionResult AddDoctor(DoctorModel model) { if (ModelState.IsValid) { var doctor = _mapper.Map(model); doctor.CreatedDate = DateTime.Now; doctor.UpdatedDate = DateTime.Now; doctor.Slug = StringUtil.RemoveSign4VietnameseString(model.Name).Replace(" ", "_"); if (model.FileImage != null) { string folder = $"UploadFiles/Images/Doctor/{DateTime.Now:yyyyMMdd}/"; doctor.ImageLink = ImageUtils.UploadFileImage(model.FileImage, folder); } _doctorRepository.Add(doctor); return RedirectToAction("Index"); } return View(); } [HttpGet("doctors/EditDoctor/{id}")] public IActionResult EditDoctor(int id) { var doctor = _doctorRepository.GetById(id); if(doctor != null) { return View(_mapper.Map(doctor)); } return RedirectToAction("Error404", "Home"); } } n ... NGHỆ VN HỌC VIỆN KHOA HỌC VÀ CƠNG NGHỆ Nguyễn Văn Thìn ỨNG DỤNG MÃ NGUỒN MỞ ELASTICSEARCH VÀO HỆ THỐNG TÌM KIẾM DANH BẠ Y TẾ HIỆU QUẢ Chuyên ngành : Hệ Thống Thông Tin Mã số : 8480104 LUẬN VĂN... dụng mã nguồn mở ElasticSearch vào hệ thống tìm kiếm danh bạ y tế hiệu quả? ?? giải vấn đề sau: - X? ?y dựng hệ thống tìm kiếm Tiếng Việt danh bạ y tế để giúp người - dùng dễ dàng tìm kiếm thơng tin... Khái niệm hệ thống tìm kiếm thơng tin 1.2.1 Khái niệm hệ thống tìm kiếm thơng tin [7] Theo Kowalski [8] định nghĩa hệ thống tìm kiếm thơng tin sau: ? ?Hệ thống truy tìm thơng tin hệ thống có khả

Ngày đăng: 20/03/2023, 09:05

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan