search refactoring
This commit is contained in:
		| @ -127,19 +127,19 @@ namespace Oqtane.Managers.Search | ||||
|                 searchContent.Title = !string.IsNullOrEmpty(page.Title) ? page.Title : page.Name; | ||||
|             } | ||||
|  | ||||
|             if (searchContent.Properties == null) | ||||
|             if (searchContent.SearchContentProperties == null) | ||||
|             { | ||||
|                 searchContent.Properties = new List<SearchContentProperty>(); | ||||
|                 searchContent.SearchContentProperties = new List<SearchContentProperty>(); | ||||
|             } | ||||
|  | ||||
|             if(!searchContent.Properties.Any(i => i.Name == Constants.SearchPageIdPropertyName)) | ||||
|             if(!searchContent.SearchContentProperties.Any(i => i.Name == Constants.SearchPageIdPropertyName)) | ||||
|             { | ||||
|                 searchContent.Properties.Add(new SearchContentProperty { Name = Constants.SearchPageIdPropertyName, Value = pageModule.PageId.ToString() }); | ||||
|                 searchContent.SearchContentProperties.Add(new SearchContentProperty { Name = Constants.SearchPageIdPropertyName, Value = pageModule.PageId.ToString() }); | ||||
|             } | ||||
|  | ||||
|             if (!searchContent.Properties.Any(i => i.Name == Constants.SearchModuleIdPropertyName)) | ||||
|             if (!searchContent.SearchContentProperties.Any(i => i.Name == Constants.SearchModuleIdPropertyName)) | ||||
|             { | ||||
|                 searchContent.Properties.Add(new SearchContentProperty { Name = Constants.SearchModuleIdPropertyName, Value = pageModule.ModuleId.ToString() }); | ||||
|                 searchContent.SearchContentProperties.Add(new SearchContentProperty { Name = Constants.SearchModuleIdPropertyName, Value = pageModule.ModuleId.ToString() }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -24,7 +24,7 @@ namespace Oqtane.Managers.Search | ||||
|         public string GetUrl(SearchResult searchResult, SearchQuery searchQuery) | ||||
|         { | ||||
|             var pageRepository = _serviceProvider.GetRequiredService<IPageRepository>(); | ||||
|             var pageIdValue = searchResult.Properties?.FirstOrDefault(i => i.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|             var pageIdValue = searchResult.SearchContentProperties?.FirstOrDefault(i => i.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|             if(!string.IsNullOrEmpty(pageIdValue) && int.TryParse(pageIdValue, out int pageId)) | ||||
|             { | ||||
|                 var page = pageRepository.GetPage(pageId); | ||||
| @ -39,7 +39,7 @@ namespace Oqtane.Managers.Search | ||||
|  | ||||
|         public bool Visible(SearchContent searchResult, SearchQuery searchQuery) | ||||
|         { | ||||
|             var pageIdValue = searchResult.Properties?.FirstOrDefault(i => i.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|             var pageIdValue = searchResult.SearchContentProperties?.FirstOrDefault(i => i.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|             if (!string.IsNullOrEmpty(pageIdValue) && int.TryParse(pageIdValue, out int pageId)) | ||||
|             { | ||||
|                 return CanViewPage(pageId, searchQuery.User); | ||||
|  | ||||
| @ -64,14 +64,14 @@ namespace Oqtane.Managers.Search | ||||
|                         IsActive = !page.IsDeleted && Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate) | ||||
|                     }; | ||||
|  | ||||
|                     if (searchContent.Properties == null) | ||||
|                     if (searchContent.SearchContentProperties == null) | ||||
|                     { | ||||
|                         searchContent.Properties = new List<SearchContentProperty>(); | ||||
|                         searchContent.SearchContentProperties = new List<SearchContentProperty>(); | ||||
|                     } | ||||
|  | ||||
|                     if (!searchContent.Properties.Any(i => i.Name == Constants.SearchPageIdPropertyName)) | ||||
|                     if (!searchContent.SearchContentProperties.Any(i => i.Name == Constants.SearchPageIdPropertyName)) | ||||
|                     { | ||||
|                         searchContent.Properties.Add(new SearchContentProperty { Name = Constants.SearchPageIdPropertyName, Value = page.PageId.ToString() }); | ||||
|                         searchContent.SearchContentProperties.Add(new SearchContentProperty { Name = Constants.SearchPageIdPropertyName, Value = page.PageId.ToString() }); | ||||
|                     } | ||||
|  | ||||
|                     searchContentList.Add(searchContent); | ||||
|  | ||||
| @ -1,42 +0,0 @@ | ||||
| using Microsoft.EntityFrameworkCore.Migrations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; | ||||
| using Oqtane.Databases.Interfaces; | ||||
|  | ||||
| namespace Oqtane.Migrations.EntityBuilders | ||||
| { | ||||
|     public class SearchContentWordsEntityBuilder : BaseEntityBuilder<SearchContentWordsEntityBuilder> | ||||
|     { | ||||
|         private const string _entityTableName = "SearchContentWords"; | ||||
|         private readonly PrimaryKey<SearchContentWordsEntityBuilder> _primaryKey = new("PK_SearchContentWords", x => x.WordId); | ||||
|         private readonly ForeignKey<SearchContentWordsEntityBuilder> _searchContentForeignKey = new("FK_SearchContentWords_SearchContent", x => x.SearchContentId, "SearchContent", "SearchContentId", ReferentialAction.Cascade); | ||||
|         private readonly ForeignKey<SearchContentWordsEntityBuilder> _wordSourceForeignKey = new("FK_SearchContentWords_WordSource", x => x.WordSourceId, "SearchContentWordSource", "WordSourceId", ReferentialAction.Cascade); | ||||
|  | ||||
|         public SearchContentWordsEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) | ||||
|         { | ||||
|             EntityTableName = _entityTableName; | ||||
|             PrimaryKey = _primaryKey; | ||||
|  | ||||
|             ForeignKeys.Add(_searchContentForeignKey); | ||||
|             ForeignKeys.Add(_wordSourceForeignKey); | ||||
|         } | ||||
|  | ||||
|         protected override SearchContentWordsEntityBuilder BuildTable(ColumnsBuilder table) | ||||
|         { | ||||
|             WordId = AddAutoIncrementColumn(table, "WordId"); | ||||
|             SearchContentId = AddIntegerColumn(table, "SearchContentId"); | ||||
|             WordSourceId = AddIntegerColumn(table, "WordSourceId"); | ||||
|             Count = AddIntegerColumn(table, "Count"); | ||||
|  | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> WordId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> SearchContentId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> WordSourceId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> Count { get; private set; } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,47 @@ | ||||
| using Microsoft.EntityFrameworkCore.Migrations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; | ||||
| using Oqtane.Databases.Interfaces; | ||||
|  | ||||
| namespace Oqtane.Migrations.EntityBuilders | ||||
| { | ||||
|     public class SearchContentWordEntityBuilder : BaseEntityBuilder<SearchContentWordEntityBuilder> | ||||
|     { | ||||
|         private const string _entityTableName = "SearchContentWord"; | ||||
|         private readonly PrimaryKey<SearchContentWordEntityBuilder> _primaryKey = new("PK_SearchContentWord", x => x.SearchWordId); | ||||
|         private readonly ForeignKey<SearchContentWordEntityBuilder> _foreignKey1 = new("FK_SearchContentWord_SearchContent", x => x.SearchContentId, "SearchContent", "SearchContentId", ReferentialAction.Cascade); | ||||
|         private readonly ForeignKey<SearchContentWordEntityBuilder> _foreignKey2 = new("FK_SearchContentWord_SearchWord", x => x.SearchWordId, "SearchWord", "SearchWordId", ReferentialAction.Cascade); | ||||
|  | ||||
|         public SearchContentWordEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) | ||||
|         { | ||||
|             EntityTableName = _entityTableName; | ||||
|             PrimaryKey = _primaryKey; | ||||
|             ForeignKeys.Add(_foreignKey1); | ||||
|             ForeignKeys.Add(_foreignKey2); | ||||
|         } | ||||
|  | ||||
|         protected override SearchContentWordEntityBuilder BuildTable(ColumnsBuilder table) | ||||
|         { | ||||
|             SearchContentWordId = AddAutoIncrementColumn(table, "SearchContentWordId"); | ||||
|             SearchContentId = AddIntegerColumn(table, "SearchContentId"); | ||||
|             SearchWordId = AddIntegerColumn(table, "SearchWordId"); | ||||
|             Count = AddIntegerColumn(table, "Count"); | ||||
|             CreatedOn = AddDateTimeColumn(table, "CreatedOn"); | ||||
|             ModifiedOn = AddDateTimeColumn(table, "ModifiedOn"); | ||||
|  | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> SearchContentWordId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> SearchContentId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> SearchWordId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> Count { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> CreatedOn { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> ModifiedOn { get; private set; } | ||||
|     } | ||||
| } | ||||
| @ -1,31 +0,0 @@ | ||||
| using Microsoft.EntityFrameworkCore.Migrations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; | ||||
| using Oqtane.Databases.Interfaces; | ||||
|  | ||||
| namespace Oqtane.Migrations.EntityBuilders | ||||
| { | ||||
|     public class SearchContentWordSourceEntityBuilder : BaseEntityBuilder<SearchContentWordSourceEntityBuilder> | ||||
|     { | ||||
|         private const string _entityTableName = "SearchContentWordSource"; | ||||
|         private readonly PrimaryKey<SearchContentWordSourceEntityBuilder> _primaryKey = new("PK_SearchContentWordSource", x => x.WordSourceId); | ||||
|  | ||||
|         public SearchContentWordSourceEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) | ||||
|         { | ||||
|             EntityTableName = _entityTableName; | ||||
|             PrimaryKey = _primaryKey; | ||||
|         } | ||||
|  | ||||
|         protected override SearchContentWordSourceEntityBuilder BuildTable(ColumnsBuilder table) | ||||
|         { | ||||
|             WordSourceId = AddAutoIncrementColumn(table, "WordSourceId"); | ||||
|             Word = AddStringColumn(table, "Word", 255); | ||||
|  | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> WordSourceId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> Word { get; private set; } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| using Microsoft.EntityFrameworkCore.Migrations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations; | ||||
| using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders; | ||||
| using Oqtane.Databases.Interfaces; | ||||
|  | ||||
| namespace Oqtane.Migrations.EntityBuilders | ||||
| { | ||||
|     public class SearchWordEntityBuilder : BaseEntityBuilder<SearchWordEntityBuilder> | ||||
|     { | ||||
|         private const string _entityTableName = "SearchWord"; | ||||
|         private readonly PrimaryKey<SearchWordEntityBuilder> _primaryKey = new("PK_SearchWord", x => x.SearchWordId); | ||||
|  | ||||
|         public SearchWordEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database) | ||||
|         { | ||||
|             EntityTableName = _entityTableName; | ||||
|             PrimaryKey = _primaryKey; | ||||
|         } | ||||
|  | ||||
|         protected override SearchWordEntityBuilder BuildTable(ColumnsBuilder table) | ||||
|         { | ||||
|             SearchWordId = AddAutoIncrementColumn(table, "SearchWordId"); | ||||
|             Word = AddStringColumn(table, "Word", 255); | ||||
|             CreatedOn = AddDateTimeColumn(table, "CreatedOn"); | ||||
|  | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> SearchWordId { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> Word { get; private set; } | ||||
|  | ||||
|         public OperationBuilder<AddColumnOperation> CreatedOn { get; private set; } | ||||
|     } | ||||
| } | ||||
| @ -23,22 +23,22 @@ namespace Oqtane.Migrations.Tenant | ||||
|             var searchContentPropertyEntityBuilder = new SearchContentPropertyEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentPropertyEntityBuilder.Create(); | ||||
|  | ||||
|             var searchContentWordSourceEntityBuilder = new SearchContentWordSourceEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordSourceEntityBuilder.Create(); | ||||
|             searchContentWordSourceEntityBuilder.AddIndex("IX_SearchContentWordSource", "Word", true); | ||||
|             var searchWordEntityBuilder = new SearchWordEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchWordEntityBuilder.Create(); | ||||
|             searchWordEntityBuilder.AddIndex("IX_SearchWord", "Word", true); | ||||
|  | ||||
|             var searchContentWordsEntityBuilder = new SearchContentWordsEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordsEntityBuilder.Create(); | ||||
|             var searchContentWordEntityBuilder = new SearchContentWordEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordEntityBuilder.Create(); | ||||
|         } | ||||
|  | ||||
|         protected override void Down(MigrationBuilder migrationBuilder) | ||||
|         { | ||||
|             var searchContentWordsEntityBuilder = new SearchContentWordsEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordsEntityBuilder.Drop(); | ||||
|             var searchContentWordEntityBuilder = new SearchContentWordEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordEntityBuilder.Drop(); | ||||
|  | ||||
|             var searchContentWordSourceEntityBuilder = new SearchContentWordSourceEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentWordSourceEntityBuilder.DropIndex("IX_SearchContentWordSource"); | ||||
|             searchContentWordSourceEntityBuilder.Drop(); | ||||
|             var searchWordEntityBuilder = new SearchWordEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchWordEntityBuilder.DropIndex("IX_SearchWord"); | ||||
|             searchWordEntityBuilder.Drop(); | ||||
|  | ||||
|             var searchContentPropertyEntityBuilder = new SearchContentPropertyEntityBuilder(migrationBuilder, ActiveDatabase); | ||||
|             searchContentPropertyEntityBuilder.Drop(); | ||||
|  | ||||
| @ -4,13 +4,11 @@ using System.Linq; | ||||
| using System.Net; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
| using System.Xml; | ||||
| using HtmlAgilityPack; | ||||
| using Oqtane.Models; | ||||
| using Oqtane.Repository; | ||||
| using Oqtane.Services; | ||||
| using Oqtane.Shared; | ||||
| using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource; | ||||
|  | ||||
| namespace Oqtane.Providers | ||||
| { | ||||
| @ -64,7 +62,7 @@ namespace Oqtane.Providers | ||||
|         { | ||||
|             var totalResults = 0; | ||||
|  | ||||
|             var searchContentList = await _searchContentRepository.GetSearchContentListAsync(searchQuery); | ||||
|             var searchContentList = await _searchContentRepository.GetSearchContentsAsync(searchQuery); | ||||
|  | ||||
|             //convert the search content to search results. | ||||
|             var results = searchContentList | ||||
| @ -107,7 +105,7 @@ namespace Oqtane.Providers | ||||
|             { | ||||
|                 if (i.EntityName == EntityNames.Page || i.EntityName == EntityNames.Module) | ||||
|                 { | ||||
|                     var pageId = i.Properties.FirstOrDefault(p => p.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|                     var pageId = i.SearchContentProperties.FirstOrDefault(p => p.Name == Constants.SearchPageIdPropertyName)?.Value ?? string.Empty; | ||||
|                     return !string.IsNullOrEmpty(pageId) ? pageId : i.UniqueKey; | ||||
|                 } | ||||
|                 else | ||||
| @ -138,7 +136,7 @@ namespace Oqtane.Providers | ||||
|                 Body = searchContent.Body, | ||||
|                 Url = searchContent.Url, | ||||
|                 ModifiedTime = searchContent.ModifiedTime, | ||||
|                 Properties = searchContent.Properties, | ||||
|                 SearchContentProperties = searchContent.SearchContentProperties, | ||||
|                 Snippet = BuildSnippet(searchContent, searchQuery), | ||||
|                 Score = CalculateScore(searchContent, searchQuery) | ||||
|             }; | ||||
| @ -151,7 +149,7 @@ namespace Oqtane.Providers | ||||
|             var score = 0f; | ||||
|             foreach (var keyword in SearchUtils.GetKeywordsList(searchQuery.Keywords)) | ||||
|             { | ||||
|                 score += searchContent.Words.Where(i => i.WordSource.Word.StartsWith(keyword)).Sum(i => i.Count); | ||||
|                 score += searchContent.SearchContentWords.Where(i => i.SearchWord.Word.StartsWith(keyword)).Sum(i => i.Count); | ||||
|             } | ||||
|  | ||||
|             return score / 100; | ||||
| @ -206,31 +204,34 @@ namespace Oqtane.Providers | ||||
|             //analyze the search content and save the index words | ||||
|             var indexContent = $"{searchContent.Title} {searchContent.Description} {searchContent.Body} {searchContent.AdditionalContent}"; | ||||
|             var words = GetWords(indexContent, WordMinLength); | ||||
|             var existWords = _searchContentRepository.GetWords(searchContent.SearchContentId); | ||||
|             var existingSearchContentWords = _searchContentRepository.GetSearchContentWords(searchContent.SearchContentId); | ||||
|             foreach (var kvp in words) | ||||
|             { | ||||
|                 var word = existWords.FirstOrDefault(i => i.WordSource.Word == kvp.Key); | ||||
|                 if (word != null) | ||||
|                 var searchContentWord = existingSearchContentWords.FirstOrDefault(i => i.SearchWord.Word == kvp.Key); | ||||
|                 if (searchContentWord != null) | ||||
|                 { | ||||
|                     word.Count = kvp.Value; | ||||
|                     _searchContentRepository.UpdateSearchContentWords(word); | ||||
|                     searchContentWord.Count = kvp.Value; | ||||
|                     searchContentWord.ModifiedOn = DateTime.UtcNow; | ||||
|                     _searchContentRepository.UpdateSearchContentWord(searchContentWord); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     var wordSource = _searchContentRepository.GetSearchContentWordSource(kvp.Key); | ||||
|                     if (wordSource == null) | ||||
|                     var searchWord = _searchContentRepository.GetSearchWord(kvp.Key); | ||||
|                     if (searchWord == null) | ||||
|                     { | ||||
|                         wordSource = _searchContentRepository.AddSearchContentWordSource(new SearchContentWordSource { Word = kvp.Key }); | ||||
|                         searchWord = _searchContentRepository.AddSearchWord(new SearchWord { Word = kvp.Key, CreatedOn = DateTime.UtcNow }); | ||||
|                     } | ||||
|  | ||||
|                     word = new SearchContentWords | ||||
|                     searchContentWord = new SearchContentWord | ||||
|                     { | ||||
|                         SearchContentId = searchContent.SearchContentId, | ||||
|                         WordSourceId = wordSource.WordSourceId, | ||||
|                         Count = kvp.Value | ||||
|                         SearchWordId = searchWord.SearchWordId, | ||||
|                         Count = kvp.Value, | ||||
|                         CreatedOn = DateTime.UtcNow, | ||||
|                         ModifiedOn = DateTime.UtcNow | ||||
|                     }; | ||||
|  | ||||
|                     _searchContentRepository.AddSearchContentWords(word); | ||||
|                     _searchContentRepository.AddSearchContentWord(searchContentWord); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -31,7 +31,7 @@ namespace Oqtane.Repository | ||||
|         public virtual DbSet<UrlMapping> UrlMapping { get; set; } | ||||
|         public virtual DbSet<SearchContent> SearchContent { get; set; } | ||||
|         public virtual DbSet<SearchContentProperty> SearchContentProperty { get; set; } | ||||
|         public virtual DbSet<SearchContentWords> SearchContentWords { get; set; } | ||||
|         public virtual DbSet<SearchContentWordSource> SearchContentWordSource { get; set; } | ||||
|         public virtual DbSet<SearchContentWord> SearchContentWord { get; set; } | ||||
|         public virtual DbSet<SearchWord> SearchWord { get; set; } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -7,18 +7,18 @@ namespace Oqtane.Repository | ||||
| { | ||||
|     public interface ISearchContentRepository | ||||
|     { | ||||
|         Task<IEnumerable<SearchContent>> GetSearchContentListAsync(SearchQuery searchQuery); | ||||
|         Task<IEnumerable<SearchContent>> GetSearchContentsAsync(SearchQuery searchQuery); | ||||
|         SearchContent AddSearchContent(SearchContent searchContent); | ||||
|         void DeleteSearchContent(int searchContentId); | ||||
|         void DeleteSearchContent(string entityName, int entryId); | ||||
|         void DeleteSearchContent(string uniqueKey); | ||||
|         void DeleteAllSearchContent(); | ||||
|  | ||||
|         SearchContentWordSource GetSearchContentWordSource(string word); | ||||
|         SearchContentWordSource AddSearchContentWordSource(SearchContentWordSource wordSource); | ||||
|         SearchWord GetSearchWord(string word); | ||||
|         SearchWord AddSearchWord(SearchWord searchWord); | ||||
|  | ||||
|         IEnumerable<SearchContentWords> GetWords(int searchContentId); | ||||
|         SearchContentWords AddSearchContentWords(SearchContentWords word); | ||||
|         SearchContentWords UpdateSearchContentWords(SearchContentWords word); | ||||
|         IEnumerable<SearchContentWord> GetSearchContentWords(int searchContentId); | ||||
|         SearchContentWord AddSearchContentWord(SearchContentWord searchContentWord); | ||||
|         SearchContentWord UpdateSearchContentWord(SearchContentWord searchContentWord); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -17,13 +17,13 @@ namespace Oqtane.Repository | ||||
|             _dbContextFactory = dbContextFactory; | ||||
|         } | ||||
|  | ||||
|         public async Task<IEnumerable<SearchContent>> GetSearchContentListAsync(SearchQuery searchQuery) | ||||
|         public async Task<IEnumerable<SearchContent>> GetSearchContentsAsync(SearchQuery searchQuery) | ||||
|         { | ||||
|             using var db = _dbContextFactory.CreateDbContext(); | ||||
|             var searchContentList = db.SearchContent.AsNoTracking() | ||||
|                 .Include(i => i.Properties) | ||||
|                 .Include(i => i.Words) | ||||
|                 .ThenInclude(w => w.WordSource) | ||||
|                 .Include(i => i.SearchContentProperties) | ||||
|                 .Include(i => i.SearchContentWords) | ||||
|                 .ThenInclude(w => w.SearchWord) | ||||
|                 .Where(i => i.SiteId == searchQuery.SiteId && i.IsActive); | ||||
|  | ||||
|             if (searchQuery.EntityNames != null && searchQuery.EntityNames.Any()) | ||||
| @ -45,7 +45,7 @@ namespace Oqtane.Repository | ||||
|             { | ||||
|                 foreach (var property in searchQuery.Properties) | ||||
|                 { | ||||
|                     searchContentList = searchContentList.Where(i => i.Properties.Any(p => p.Name == property.Key && p.Value == property.Value)); | ||||
|                     searchContentList = searchContentList.Where(i => i.SearchContentProperties.Any(p => p.Name == property.Key && p.Value == property.Value)); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -54,7 +54,7 @@ namespace Oqtane.Repository | ||||
|             { | ||||
|                 foreach (var keyword in SearchUtils.GetKeywordsList(searchQuery.Keywords)) | ||||
|                 { | ||||
|                     filteredContentList.AddRange(await searchContentList.Where(i => i.Words.Any(w => w.WordSource.Word.StartsWith(keyword))).ToListAsync()); | ||||
|                     filteredContentList.AddRange(await searchContentList.Where(i => i.SearchContentWords.Any(w => w.SearchWord.Word.StartsWith(keyword))).ToListAsync()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -66,9 +66,9 @@ namespace Oqtane.Repository | ||||
|             using var context = _dbContextFactory.CreateDbContext(); | ||||
|             context.SearchContent.Add(searchContent); | ||||
|  | ||||
|             if(searchContent.Properties != null && searchContent.Properties.Any()) | ||||
|             if(searchContent.SearchContentProperties != null && searchContent.SearchContentProperties.Any()) | ||||
|             { | ||||
|                 foreach(var property in searchContent.Properties) | ||||
|                 foreach(var property in searchContent.SearchContentProperties) | ||||
|                 { | ||||
|                     property.SearchContentId = searchContent.SearchContentId; | ||||
|                     context.SearchContentProperty.Add(property); | ||||
| @ -117,7 +117,7 @@ namespace Oqtane.Repository | ||||
|             db.SaveChanges(); | ||||
|         } | ||||
|  | ||||
|         public SearchContentWordSource GetSearchContentWordSource(string word) | ||||
|         public SearchWord GetSearchWord(string word) | ||||
|         { | ||||
|             if(string.IsNullOrEmpty(word)) | ||||
|             { | ||||
| @ -125,45 +125,45 @@ namespace Oqtane.Repository | ||||
|             } | ||||
|  | ||||
|             using var db = _dbContextFactory.CreateDbContext(); | ||||
|             return db.SearchContentWordSource.FirstOrDefault(i => i.Word == word); | ||||
|             return db.SearchWord.FirstOrDefault(i => i.Word == word); | ||||
|         } | ||||
|  | ||||
|         public SearchContentWordSource AddSearchContentWordSource(SearchContentWordSource wordSource) | ||||
|         public SearchWord AddSearchWord(SearchWord searchWord) | ||||
|         { | ||||
|                 using var db = _dbContextFactory.CreateDbContext(); | ||||
|  | ||||
|                 db.SearchContentWordSource.Add(wordSource); | ||||
|                 db.SearchWord.Add(searchWord); | ||||
|                 db.SaveChanges(); | ||||
|  | ||||
|                 return wordSource; | ||||
|                 return searchWord; | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<SearchContentWords> GetWords(int searchContentId) | ||||
|         public IEnumerable<SearchContentWord> GetSearchContentWords(int searchContentId) | ||||
|         { | ||||
|             using var db = _dbContextFactory.CreateDbContext(); | ||||
|             return db.SearchContentWords | ||||
|                 .Include(i => i.WordSource) | ||||
|             return db.SearchContentWord | ||||
|                 .Include(i => i.SearchWord) | ||||
|                 .Where(i => i.SearchContentId == searchContentId).ToList(); | ||||
|         } | ||||
|  | ||||
|         public SearchContentWords AddSearchContentWords(SearchContentWords word) | ||||
|         public SearchContentWord AddSearchContentWord(SearchContentWord searchContentWord) | ||||
|         { | ||||
|                 using var db = _dbContextFactory.CreateDbContext(); | ||||
|                  | ||||
|                 db.SearchContentWords.Add(word); | ||||
|                 db.SearchContentWord.Add(searchContentWord); | ||||
|                 db.SaveChanges(); | ||||
|  | ||||
|                 return word; | ||||
|                 return searchContentWord; | ||||
|         } | ||||
|  | ||||
|         public SearchContentWords UpdateSearchContentWords(SearchContentWords word) | ||||
|         public SearchContentWord UpdateSearchContentWord(SearchContentWord searchContentWord) | ||||
|         { | ||||
|             using var db = _dbContextFactory.CreateDbContext(); | ||||
|  | ||||
|             db.Entry(word).State = EntityState.Modified; | ||||
|             db.Entry(searchContentWord).State = EntityState.Modified; | ||||
|             db.SaveChanges(); | ||||
|  | ||||
|             return word; | ||||
|             return searchContentWord; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -31,9 +31,9 @@ namespace Oqtane.Models | ||||
|  | ||||
|         public string AdditionalContent { get; set; } | ||||
|  | ||||
|         public IList<SearchContentProperty> Properties { get; set; } | ||||
|         public IList<SearchContentProperty> SearchContentProperties { get; set; } | ||||
|  | ||||
|         public IList<SearchContentWords> Words { get; set; } | ||||
|         public IList<SearchContentWord> SearchContentWords { get; set; } | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|  | ||||
							
								
								
									
										24
									
								
								Oqtane.Shared/Models/SearchContentWord.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Oqtane.Shared/Models/SearchContentWord.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| using System; | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
|  | ||||
| namespace Oqtane.Models | ||||
| { | ||||
|     public class SearchContentWord | ||||
|     { | ||||
|         [Key] | ||||
|         public int SearchContentWordId { get; set; } | ||||
|  | ||||
|         public int SearchContentId { get; set; } | ||||
|  | ||||
|         public int SearchWordId { get; set; } | ||||
|  | ||||
|         public int Count { get; set; } | ||||
|  | ||||
|         public DateTime CreatedOn { get; set; } | ||||
|  | ||||
|         public DateTime ModifiedOn { get; set; } | ||||
|  | ||||
|         public SearchWord SearchWord { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -1,19 +0,0 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
|  | ||||
| namespace Oqtane.Models | ||||
| { | ||||
|     public class SearchContentWords | ||||
|     { | ||||
|         [Key] | ||||
|         public int WordId { get; set; } | ||||
|  | ||||
|         public int SearchContentId { get; set; } | ||||
|  | ||||
|         public int WordSourceId { get; set; } | ||||
|  | ||||
|         public int Count { get; set; } | ||||
|  | ||||
|         public SearchContentWordSource WordSource { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -1,12 +1,15 @@ | ||||
| using System; | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| 
 | ||||
| namespace Oqtane.Models | ||||
| { | ||||
|     public class SearchContentWordSource | ||||
|     public class SearchWord | ||||
|     { | ||||
|         [Key] | ||||
|         public int WordSourceId { get; set; } | ||||
|         public int SearchWordId { get; set; } | ||||
| 
 | ||||
|         public string Word { get; set; } | ||||
| 
 | ||||
|         public DateTime CreatedOn { get; set; } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 sbwalker
					sbwalker