SearchEngineTests.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using Masuit.LuceneEFCore.SearchEngine.Interfaces;
  2. using Masuit.LuceneEFCore.SearchEngine.Test.Helpers;
  3. using Masuit.LuceneEFCore.SearchEngine.Test.Models;
  4. using Microsoft.EntityFrameworkCore;
  5. using System.Linq;
  6. using Xunit;
  7. using Xunit.Abstractions;
  8. namespace Masuit.LuceneEFCore.SearchEngine.Test
  9. {
  10. [Trait("Category", "SearchContext")]
  11. public class SearchEngineTests
  12. {
  13. private TestDbContext _context;
  14. private readonly ITestOutputHelper _output;
  15. string _tempName;
  16. public SearchEngineTests(ITestOutputHelper output)
  17. {
  18. _output = output;
  19. }
  20. private void InitializeContext()
  21. {
  22. _tempName = System.IO.Path.GetTempFileName();
  23. var dboptions = new DbContextOptionsBuilder<TestDbContext>().UseInMemoryDatabase(databaseName: _tempName).Options;
  24. _context = new TestDbContext(dboptions);
  25. }
  26. [Fact]
  27. public void AContextProviderCanIndexADatabase()
  28. {
  29. InitializeContext();
  30. LuceneIndexerOptions options = new LuceneIndexerOptions
  31. {
  32. UseRamDirectory = true
  33. };
  34. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  35. searchProvider.CreateIndex();
  36. Assert.Equal(2000, searchProvider.IndexCount);
  37. // cleanup
  38. searchProvider.DeleteIndex();
  39. }
  40. [Fact]
  41. public void AContextCanBeSearchedUsingAContextProvider()
  42. {
  43. InitializeContext();
  44. LuceneIndexerOptions options = new LuceneIndexerOptions
  45. {
  46. UseRamDirectory = true
  47. };
  48. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  49. searchProvider.CreateIndex();
  50. SearchOptions searchOptions = new SearchOptions("John", "FirstName");
  51. // test
  52. var results = searchProvider.ScoredSearch<User>(searchOptions);
  53. Assert.Equal(5, results.TotalHits);
  54. // cleanup
  55. searchProvider.DeleteIndex();
  56. }
  57. [Fact]
  58. public void SkipAndTakeWorkWhenSearchingUsingAContextProvider()
  59. {
  60. InitializeContext();
  61. LuceneIndexerOptions options = new LuceneIndexerOptions
  62. {
  63. UseRamDirectory = true
  64. };
  65. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  66. searchProvider.CreateIndex();
  67. SearchOptions searchOptions = new SearchOptions("John", "FirstName");
  68. // test
  69. var initialResults = searchProvider.ScoredSearch<User>(searchOptions);
  70. int lastId = initialResults.Results[4].Entity.Id;
  71. Assert.Equal(5, initialResults.TotalHits);
  72. Assert.Equal(5, initialResults.Results.Count);
  73. searchOptions.Skip = 4;
  74. searchOptions.Take = 1;
  75. var subResults = searchProvider.ScoredSearch<User>(searchOptions);
  76. Assert.Equal(5, subResults.TotalHits);
  77. Assert.Equal(1, subResults.Results.Count);
  78. Assert.Equal(lastId, subResults.Results.First().Entity.Id);
  79. // cleanup
  80. searchProvider.DeleteIndex();
  81. }
  82. [Fact]
  83. public void AContextCanBeSearchedUsingAWildCard()
  84. {
  85. InitializeContext();
  86. LuceneIndexerOptions options = new LuceneIndexerOptions
  87. {
  88. UseRamDirectory = true
  89. };
  90. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  91. searchProvider.CreateIndex();
  92. SearchOptions searchOptions = new SearchOptions("Joh*", "FirstName");
  93. // test
  94. var results = searchProvider.ScoredSearch<User>(searchOptions);
  95. PrintResult(results);
  96. Assert.Equal(10, results.TotalHits);
  97. // cleanup
  98. searchProvider.DeleteIndex();
  99. }
  100. [Fact]
  101. public void ASearchWillReturnTheSameResultsAsAScoredSearch()
  102. {
  103. InitializeContext();
  104. LuceneIndexerOptions options = new LuceneIndexerOptions
  105. {
  106. UseRamDirectory = true
  107. };
  108. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  109. searchProvider.CreateIndex();
  110. SearchOptions searchOptions = new SearchOptions("Joh*", "FirstName");
  111. // test
  112. var results = searchProvider.Search<User>(searchOptions);
  113. Assert.Equal(10, results.TotalHits);
  114. // cleanup
  115. searchProvider.DeleteIndex();
  116. }
  117. [Fact]
  118. public void AScoredSearchWillOrderByRelevence()
  119. {
  120. InitializeContext();
  121. LuceneIndexerOptions options = new LuceneIndexerOptions
  122. {
  123. UseRamDirectory = true
  124. };
  125. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  126. searchProvider.CreateIndex();
  127. SearchOptions searchOptions = new SearchOptions("Burns", "FirstName,Surname");
  128. var results = searchProvider.ScoredSearch<User>(searchOptions);
  129. var first = results.Results.First().Entity;
  130. var highest = results.Results.First().Score;
  131. var lowest = results.Results.Last().Score;
  132. Assert.True(highest > lowest);
  133. Assert.Equal("Jeremy", first.FirstName);
  134. Assert.Equal("Burns", first.Surname);
  135. searchProvider.DeleteIndex();
  136. }
  137. [Fact]
  138. public void ASearchWillStillOrderByRelevence()
  139. {
  140. InitializeContext();
  141. LuceneIndexerOptions options = new LuceneIndexerOptions
  142. {
  143. UseRamDirectory = true
  144. };
  145. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  146. searchProvider.CreateIndex();
  147. SearchOptions searchOptions = new SearchOptions("Jeremy Burns", "FirstName,Surname");
  148. var results = searchProvider.Search<User>(searchOptions);
  149. var first = results.Results.First();
  150. Assert.Equal("Jeremy", first.FirstName);
  151. Assert.Equal("Burns", first.Surname);
  152. searchProvider.DeleteIndex();
  153. }
  154. [Fact]
  155. public void ASearchCanOrderByMultipleFields()
  156. {
  157. InitializeContext();
  158. LuceneIndexerOptions options = new LuceneIndexerOptions
  159. {
  160. UseRamDirectory = true
  161. };
  162. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  163. User jc = new User()
  164. {
  165. FirstName = "John",
  166. Surname = "Chapman",
  167. JobTitle = "Test Engineer",
  168. Email = "[email protected]"
  169. };
  170. _context.Users.Add(jc);
  171. _context.SaveChanges();
  172. searchProvider.CreateIndex();
  173. SearchOptions search = new SearchOptions("John", "FirstName", 1000, null, null, "Surname,JobTitle");
  174. var results = searchProvider.ScoredSearch<User>(search);
  175. var topResult = results.Results[0];
  176. var secondResult = results.Results[1];
  177. Assert.Equal("Sales Associate", topResult.Entity.JobTitle);
  178. Assert.Equal("Test Engineer", secondResult.Entity.JobTitle);
  179. searchProvider.DeleteIndex();
  180. }
  181. [Fact]
  182. public void SaveChangesUpdatesEntitiesAddedToTheIndex()
  183. {
  184. InitializeContext();
  185. LuceneIndexerOptions options = new LuceneIndexerOptions
  186. {
  187. UseRamDirectory = true
  188. };
  189. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  190. searchProvider.CreateIndex();
  191. var newUser = new User()
  192. {
  193. FirstName = "Duke",
  194. Surname = "Nukem",
  195. Email = "[email protected]",
  196. JobTitle = "Shooty Man"
  197. };
  198. var search = new SearchOptions("Nukem", "Surname");
  199. var initialResults = searchProvider.Search<User>(search);
  200. searchProvider.Context.Users.Add(newUser);
  201. searchProvider.SaveChanges();
  202. var newResults = searchProvider.Search<User>(search);
  203. Assert.Equal(0, initialResults.TotalHits);
  204. Assert.Equal(1, newResults.TotalHits);
  205. Assert.Equal(newUser.Id, newResults.Results[0].Id);
  206. }
  207. [Fact]
  208. public void NonValidEntitiesAreIgnored()
  209. {
  210. InitializeContext();
  211. LuceneIndexerOptions options = new LuceneIndexerOptions
  212. {
  213. UseRamDirectory = true
  214. };
  215. SearchEngine<TestDbContext> searchProvider = new SearchEngine<TestDbContext>(options, _context);
  216. searchProvider.CreateIndex();
  217. Assert.True(searchProvider.IndexCount > 0);
  218. }
  219. private void PrintResult(IScoredSearchResultCollection<User> results)
  220. {
  221. _output.WriteLine($"Total Hist: {results.TotalHits}\tTime Taken: {results.Elapsed}");
  222. foreach (IScoredSearchResult<User> item in results.Results)
  223. {
  224. _output.WriteLine($"Score: {item.Score}\tName:{item.Entity.FirstName}\tSurname: {item.Entity.Surname}\tEmail: {item.Entity.Email}");
  225. }
  226. }
  227. }
  228. }