semantic search

This commit is contained in:
Hamid Reza Mohammadi 2026-09-09 13:17:21 +03:30
parent 0762f19fb4
commit e42cc5d8eb
4 changed files with 70 additions and 2 deletions

View File

@ -9,10 +9,12 @@ using RMuseum.Models.Auth.Memory;
using RMuseum.Models.Auth.ViewModel;
using RMuseum.Models.Ganjoor;
using RMuseum.Models.Ganjoor.PublicExport;
using RMuseum.Models.Ganjoor.SemanticSearch;
using RMuseum.Models.Ganjoor.ViewModels;
using RMuseum.Models.GanjoorAudio.ViewModels;
using RMuseum.Models.GanjoorIntegration;
using RMuseum.Services;
using RMuseum.Services.Implementation;
using RSecurityBackend.Models.Auth.Memory;
using RSecurityBackend.Models.Auth.ViewModels;
using RSecurityBackend.Models.Generic;
@ -5021,6 +5023,31 @@ namespace RMuseum.Controllers
}
/// <summary>
/// semantic ("find a poem about...") search
/// </summary>
[HttpPost("search/semantic")]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task<IActionResult> SemanticSearch([FromBody] SemanticSearchRequestDto request)
{
try
{
var result = await _semanticSearchService.SearchAsync(request.Query, request.TopK);
return Ok(result);
}
catch (ArgumentException exp)
{
return BadRequest(exp.Message);
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
/// <summary>
/// readonly mode
@ -5089,6 +5116,9 @@ namespace RMuseum.Controllers
/// </summary>
protected IConfiguration Configuration { get; }
protected ISemanticSearchService _semanticSearchService;
/// <summary>
/// constructor
/// </summary>
@ -5098,13 +5128,15 @@ namespace RMuseum.Controllers
/// <param name="imageFileService"></param>
/// <param name="memoryCache"></param>
/// <param name="configuration"></param>
/// <param name="semanticSearchService"></param>
public GanjoorController(
IGanjoorService ganjoorService,
IAppUserService appUserService,
IHttpContextAccessor httpContextAccessor,
IImageFileService imageFileService,
IMemoryCache memoryCache,
IConfiguration configuration
IConfiguration configuration,
ISemanticSearchService semanticSearchService
)
{
_ganjoorService = ganjoorService;
@ -5113,6 +5145,7 @@ namespace RMuseum.Controllers
_imageFileService = imageFileService;
_memoryCache = memoryCache;
Configuration = configuration;
_semanticSearchService = semanticSearchService;
}
}
}

View File

@ -2644,6 +2644,11 @@
<param name="correction"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.GanjoorController.SemanticSearch(RMuseum.Models.Ganjoor.SemanticSearch.SemanticSearchRequestDto)">
<summary>
semantic ("find a poem about...") search
</summary>
</member>
<member name="P:RMuseum.Controllers.GanjoorController.ReadOnlyMode">
<summary>
readonly mode
@ -2684,7 +2689,7 @@
Configuration
</summary>
</member>
<member name="M:RMuseum.Controllers.GanjoorController.#ctor(RMuseum.Services.IGanjoorService,RSecurityBackend.Services.IAppUserService,Microsoft.AspNetCore.Http.IHttpContextAccessor,RSecurityBackend.Services.IImageFileService,Microsoft.Extensions.Caching.Memory.IMemoryCache,Microsoft.Extensions.Configuration.IConfiguration)">
<member name="M:RMuseum.Controllers.GanjoorController.#ctor(RMuseum.Services.IGanjoorService,RSecurityBackend.Services.IAppUserService,Microsoft.AspNetCore.Http.IHttpContextAccessor,RSecurityBackend.Services.IImageFileService,Microsoft.Extensions.Caching.Memory.IMemoryCache,Microsoft.Extensions.Configuration.IConfiguration,RMuseum.Services.Implementation.ISemanticSearchService)">
<summary>
constructor
</summary>
@ -2694,6 +2699,7 @@
<param name="imageFileService"></param>
<param name="memoryCache"></param>
<param name="configuration"></param>
<param name="semanticSearchService"></param>
</member>
<member name="M:RMuseum.Controllers.GanjoorPoetSuggestedPhotosController.GetPoetSuggestedPhotosAsync(System.Int32)">
<summary>

View File

@ -21,6 +21,7 @@ using RMuseum.Models.Auth.Memory;
using RMuseum.Services;
using RMuseum.Services.Implementation;
using RMuseum.Services.Implementationa;
using RMuseum.Utils.SemanticSearch;
using RSecurityBackend.Authorization;
using RSecurityBackend.DbContext;
using RSecurityBackend.Models.Auth.Db;
@ -326,6 +327,27 @@ namespace RMuseum
services.AddOpenAIService();
services.AddSingleton<EmbeddingIndex>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
string dir = config["SemanticSearch:EmbeddingsDirectory"];
return EmbeddingIndex.Load(dir);
});
services.AddSingleton<QueryEmbedder>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
int dimension = int.Parse(config["SemanticSearch:Dimension"] ?? "1024");
return new QueryEmbedder(
config["SemanticSearch:ModelPath"],
config["SemanticSearch:VocabPath"],
config["SemanticSearch:MergesPath"],
dimension);
});
services.AddSingleton<ISemanticSearchService, SemanticSearchService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -111,6 +111,13 @@
"RootUrl": "https://i.ganjoor.net/images",
"LoadFromExternalServer": "True"
},
"SemanticSearch": {
"EmbeddingsDirectory": "C:\\ganjoor-embeddings-data",
"ModelPath": "C:\\ganjoor-model\\onnx\\model_quantized.onnx",
"VocabPath": "C:\\ganjoor-model\\vocab.json",
"MergesPath": "C:\\ganjoor-model\\merges.txt",
"Dimension": "1024"
},
"WebServiceUrl": "http://localhost:3439",
"ReadOnlyMode": "False",
"TransilerateFormData": "ctl00%24ContentPlaceHolder2%24ScriptManager1=ctl00%24ContentPlaceHolder2%24UpdatePanel1%7Cctl00%24ContentPlaceHolder2%24btnConvert&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=50SiwtZgcWB3spddjuBb6BloHj933fgmboKNaKJBIwGTAAKq9eDHSPq%2FLjZZI2sJIMOfywb%2FVO3ZWSadvUsRVLOnxPleQwkf3EHhZT9mSeNvEFld9VKQZ0ben0y15vOMMCfoPQ%3D%3D&__VIEWSTATEGENERATOR=82B657B9&__EVENTVALIDATION=wcYH3JuIbMl7ulzDUUsJdcDMJwjBkZ%2BEyx5Gwv7F31G5yIN75QiuxDkD7acnJpR6cBC8VNNEowaHZB5xRMOF7%2BMhsiZ3AugxyWjaeeiiAUvv1BugkbhRft4aXkJpVd3%2FaeYBHFAyDrKDkYIA2jFrmtjkj1NrtRl5uSvsFY5fPVt9antJQ8kgNRfDEeNtsBzU6BH%2FCw%3D%3D&ctl00%24ContentPlaceHolder2%24txtPersian=%D8%AD%D8%B3%D9%86&ctl00%24ContentPlaceHolder2%24txtSuggest=&__ASYNCPOST=true&ctl00%24ContentPlaceHolder2%24btnConvert=%D8%A8%D8%B1%DA%AF%D8%B1%D8%AF%D8%A7%D9%86",