/ToMigrate/Raven.Tests/Bugs/FullTextSearchOnTags.cs

https://github.com/fitzchak/ravendb · C# · 518 lines · 452 code · 66 blank · 0 comment · 10 complexity · 06d5bd92d1487365e0b07f66ffd6eb14 MD5 · raw file

  1. using System.Collections.Generic;
  2. using Raven.Abstractions.Data;
  3. using Raven.Abstractions.Indexing;
  4. using Raven.Client;
  5. using Raven.Tests.Common;
  6. using Xunit;
  7. using Raven.Client.Linq;
  8. using System.Linq;
  9. namespace Raven.Tests.Bugs
  10. {
  11. public class FullTextSearchOnTags : RavenTest
  12. {
  13. public class Image
  14. {
  15. public string Id { get; set; }
  16. public string Name { get; set; }
  17. public ICollection<string> Users { get; set; }
  18. public ICollection<string> Tags { get; set; }
  19. }
  20. [Fact]
  21. public void CanSearchUsingPhrase()
  22. {
  23. using (var store = NewDocumentStore())
  24. {
  25. using (var session = store.OpenSession())
  26. {
  27. session.Store(new Image
  28. {
  29. Tags = new[] { "cats", "animal", "feline" }
  30. });
  31. session.SaveChanges();
  32. }
  33. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  34. {
  35. Map = "from doc in docs.Images select new { doc.Tags }",
  36. });
  37. using (var session = store.OpenSession())
  38. {
  39. var images = session.Query<Image>("test")
  40. .Customize(x => x.WaitForNonStaleResults())
  41. .Search(x => x.Tags, "i love cats")
  42. .ToList();
  43. Assert.NotEmpty(images);
  44. }
  45. }
  46. }
  47. [Fact]
  48. public void CanSearchUsingPhraseAndOrderBy()
  49. {
  50. using (var store = NewDocumentStore())
  51. {
  52. using (var session = store.OpenSession())
  53. {
  54. session.Store(new Image
  55. {
  56. Name = "B",
  57. Tags = new[] { "cats", "animal", "feline" }
  58. });
  59. session.Store(new Image
  60. {
  61. Name = "A",
  62. Tags = new[] { "cats", "animal", "feline" }
  63. });
  64. session.SaveChanges();
  65. }
  66. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  67. {
  68. Map = "from doc in docs.Images select new { doc.Tags,doc.Name }",
  69. });
  70. using (var session = store.OpenSession())
  71. {
  72. var images = session.Query<Image>("test")
  73. .Customize(x => x.WaitForNonStaleResults())
  74. .OrderBy(x => x.Name)
  75. .Search(x => x.Tags, "i love cats")
  76. .ToList();
  77. Assert.NotEmpty(images);
  78. Assert.Equal("images/2", images[0].Id);
  79. Assert.Equal("images/1", images[1].Id);
  80. }
  81. }
  82. }
  83. [Fact]
  84. public void CanSearchUsingPhrase_MultipleSearches()
  85. {
  86. using (var store = NewDocumentStore())
  87. {
  88. using (var session = store.OpenSession())
  89. {
  90. session.Store(new Image
  91. {
  92. Tags = new[] { "cats", "animal", "feline" }
  93. });
  94. session.Store(new Image
  95. {
  96. Tags = new[] { "dogs", "animal", "canine" }
  97. });
  98. session.SaveChanges();
  99. }
  100. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  101. {
  102. Map = "from doc in docs.Images select new { doc.Tags }",
  103. });
  104. using (var session = store.OpenSession())
  105. {
  106. var images = session.Query<Image>("test")
  107. .Customize(x => x.WaitForNonStaleResults())
  108. .Search(x => x.Tags, "i love cats")
  109. .Search(x => x.Tags, "canine love")
  110. .ToList();
  111. Assert.Equal(2, images.Count);
  112. }
  113. }
  114. }
  115. [Fact]
  116. public void StandardSearchWillProduceExpectedResult()
  117. {
  118. using (var store = NewDocumentStore())
  119. {
  120. using (var session = store.OpenSession())
  121. {
  122. var ravenQueryable = session.Query<Image>("test")
  123. .Customize(x => x.WaitForNonStaleResults())
  124. .Search(x => x.Tags, "i love cats")
  125. .Where(x => x.Name == "User");
  126. Assert.Equal("Tags:(i love cats) AND (Name:User)", ravenQueryable.ToString());
  127. }
  128. }
  129. }
  130. [Fact]
  131. public void SearchCanUseAnd2()
  132. {
  133. using (var store = NewDocumentStore())
  134. {
  135. using (var session = store.OpenSession())
  136. {
  137. var ravenQueryable = session.Query<Image>("test")
  138. .Customize(x => x.WaitForNonStaleResults())
  139. .Where(x => x.Name == "User")
  140. .Search(x => x.Tags, "i love cats", options: SearchOptions.And);
  141. Assert.Equal("Name:User AND Tags:(i love cats)", ravenQueryable.ToString());
  142. }
  143. }
  144. }
  145. [Fact]
  146. public void SearchCanUseAnd()
  147. {
  148. using (var store = NewDocumentStore())
  149. {
  150. using (var session = store.OpenSession())
  151. {
  152. var ravenQueryable = session.Query<Image>("test")
  153. .Customize(x => x.WaitForNonStaleResults())
  154. .Search(x => x.Tags, "i love cats", options: SearchOptions.And)
  155. .Where(x => x.Name == "User");
  156. Assert.Equal("Tags:(i love cats) AND (Name:User)", ravenQueryable.ToString());
  157. }
  158. }
  159. }
  160. [Fact]
  161. public void SearchCanUseOr()
  162. {
  163. using (var store = NewDocumentStore())
  164. {
  165. using (var session = store.OpenSession())
  166. {
  167. var ravenQueryable = session.Query<Image>("test")
  168. .Customize(x => x.WaitForNonStaleResults())
  169. .Search(x => x.Tags, "i love cats", options: SearchOptions.Or)
  170. .Where(x => x.Name == "User");
  171. Assert.Equal("Tags:(i love cats) Name:User", ravenQueryable.ToString());
  172. }
  173. }
  174. }
  175. [Fact]
  176. public void SearchWillUseGuessByDefault()
  177. {
  178. using (var store = NewDocumentStore())
  179. {
  180. using (var session = store.OpenSession())
  181. {
  182. var ravenQueryable = session.Query<Image>("test")
  183. .Customize(x => x.WaitForNonStaleResults())
  184. .Search(x => x.Tags, "i love cats")
  185. .Search(x => x.Users, "i love cats")
  186. .Where(x => x.Name == "User");
  187. Assert.Equal("( Tags:(i love cats) Users:(i love cats)) AND (Name:User)", ravenQueryable.ToString());
  188. }
  189. }
  190. }
  191. [Fact]
  192. public void ActuallySearchWithAndAndNot()
  193. {
  194. using (var store = NewDocumentStore())
  195. {
  196. using (var session = store.OpenSession())
  197. {
  198. session.Store(new Image
  199. {
  200. Tags = new string[] { "cats" },
  201. Name = "User"
  202. });
  203. session.Store(new Image
  204. {
  205. Tags = new string[] { "dogs" },
  206. Name = "User"
  207. });
  208. session.SaveChanges();
  209. }
  210. using (var session = store.OpenSession())
  211. {
  212. var ravenQueryable = session.Query<Image>()
  213. .Customize(x => x.WaitForNonStaleResults())
  214. .Search(x => x.Tags, "i love cats", options: SearchOptions.And | SearchOptions.Not)
  215. .Where(x => x.Name == "User");
  216. Assert.Equal("( -Tags:(i love cats) AND Tags:(*)) AND (Name:User)", ravenQueryable.ToString());
  217. Assert.Equal(1, ravenQueryable.Count());
  218. }
  219. }
  220. }
  221. [Fact]
  222. public void SearchCanUseNot()
  223. {
  224. using (var store = NewDocumentStore())
  225. {
  226. using (var session = store.OpenSession())
  227. {
  228. var ravenQueryable = session.Query<Image>("test")
  229. .Customize(x => x.WaitForNonStaleResults())
  230. .Search(x => x.Tags, "i love cats", options: SearchOptions.Not)
  231. .Where(x => x.Name == "User");
  232. Assert.Equal("( -Tags:(i love cats) AND Tags:(*)) Name:User", ravenQueryable.ToString());
  233. }
  234. }
  235. }
  236. [Fact]
  237. public void SearchCanUseNotAndAnd()
  238. {
  239. using (var store = NewDocumentStore())
  240. {
  241. using (var session = store.OpenSession())
  242. {
  243. var ravenQueryable = session.Query<Image>("test")
  244. .Customize(x => x.WaitForNonStaleResults())
  245. .Search(x => x.Tags, "i love cats", options: SearchOptions.Not | SearchOptions.And)
  246. .Where(x => x.Name == "User");
  247. Assert.Equal("( -Tags:(i love cats) AND Tags:(*)) AND (Name:User)", ravenQueryable.ToString());
  248. }
  249. }
  250. }
  251. [Fact]
  252. public void BoostingSearches()
  253. {
  254. using (var store = NewDocumentStore())
  255. {
  256. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  257. {
  258. Map = "from doc in docs.Images select new { doc.Tags }",
  259. });
  260. using (var session = store.OpenSession())
  261. {
  262. session.Store(new Image
  263. {
  264. Tags = new[] { "cats", "animal", "feline" }
  265. });
  266. session.Store(new Image
  267. {
  268. Tags = new[] { "dogs", "animal", "canine" }
  269. });
  270. session.Store(new Image
  271. {
  272. Tags = new[] { "bugs", "resolving", "tricky" }
  273. });
  274. session.SaveChanges();
  275. }
  276. using (var session = store.OpenSession())
  277. {
  278. var ravenQueryable = session.Query<Image>("test")
  279. .Customize(x => x.WaitForNonStaleResults())
  280. .Search(x => x.Tags, "i love cats", boost: 3)
  281. .Search(x => x.Tags, "i love bugs", boost: 20)
  282. .Search(x => x.Tags, "canine love", boost: 13);
  283. var s = ravenQueryable
  284. .ToString();
  285. Assert.Equal("( Tags:(i love cats)^3 Tags:(i love bugs)^20 Tags:(canine love)^13)", s);
  286. var images = ravenQueryable.ToList();
  287. Assert.Equal(3, images.Count);
  288. Assert.Equal("images/2", images[1].Id);
  289. Assert.Equal("images/1", images[2].Id);
  290. Assert.Equal("images/3", images[0].Id);
  291. }
  292. }
  293. }
  294. [Fact]
  295. public void MultipleSearches()
  296. {
  297. using (var store = NewDocumentStore())
  298. {
  299. using (var session = store.OpenSession())
  300. {
  301. session.Store(new Image
  302. {
  303. Tags = new[] { "cats", "animal", "feline" },
  304. Users = new[] { "oren", "ayende" }
  305. });
  306. session.SaveChanges();
  307. }
  308. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  309. {
  310. Map = "from doc in docs.Images select new { doc.Tags, doc.Users }",
  311. });
  312. using (var session = store.OpenSession())
  313. {
  314. var query = session.Query<Image>("test")
  315. .Customize(x => x.WaitForNonStaleResults())
  316. .Search(x => x.Tags, "i love cats")
  317. .Search(x => x.Users, "oren")
  318. .ToString();
  319. Assert.Equal("( Tags:(i love cats) Users:(oren))", query.Trim());
  320. }
  321. }
  322. }
  323. [Fact]
  324. public void UsingSuggest()
  325. {
  326. using (var store = NewDocumentStore())
  327. {
  328. using (var session = store.OpenSession())
  329. {
  330. session.Store(new Image
  331. {
  332. Tags = new[] { "cats", "animal", "feline" },
  333. Users = new[] { "oren", "ayende" }
  334. });
  335. session.SaveChanges();
  336. }
  337. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  338. {
  339. Map = "from doc in docs.Images select new { doc.Tags, doc.Users }",
  340. Indexes = { { "Tags", FieldIndexing.Analyzed } },
  341. SuggestionsOptions = new HashSet<string> { "Tags" }
  342. });
  343. using (var session = store.OpenSession())
  344. {
  345. session.Query<Image>("test")
  346. .Customize(x => x.WaitForNonStaleResults())
  347. .ToList();
  348. var query = session.Query<Image>("test")
  349. .Search(x => x.Tags, "animal lover")
  350. .Suggest();
  351. Assert.NotEmpty(query.Suggestions);
  352. Assert.Equal("animal", query.Suggestions[0]);
  353. }
  354. }
  355. }
  356. [Fact]
  357. public void Can_search_inner_words()
  358. {
  359. using (var store = NewDocumentStore())
  360. {
  361. using (var session = store.OpenSession())
  362. {
  363. session.Store(new Image { Id = "1", Name = "Great Photo buddy" });
  364. session.Store(new Image { Id = "2", Name = "Nice Photo of the sky" });
  365. session.SaveChanges();
  366. }
  367. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  368. {
  369. Map = "from doc in docs.Images select new { doc.Name }",
  370. Indexes = {
  371. { "Name", FieldIndexing.Analyzed }
  372. }
  373. });
  374. using (var session = store.OpenSession())
  375. {
  376. var images = session.Query<Image>("test")
  377. .Customize(x => x.WaitForNonStaleResults())
  378. .OrderBy(x => x.Name)
  379. .Search(x => x.Name, "Photo")
  380. .ToList();
  381. Assert.NotEmpty(images);
  382. }
  383. }
  384. }
  385. [Fact]
  386. public void Can_search_inner_words_with_extra_condition()
  387. {
  388. using (var store = NewDocumentStore())
  389. {
  390. using (var session = store.OpenSession())
  391. {
  392. session.Store(new Image { Id = "1", Name = "Great Photo buddy" });
  393. session.Store(new Image { Id = "2", Name = "Nice Photo of the sky" });
  394. session.SaveChanges();
  395. }
  396. store.DatabaseCommands.PutIndex("test", new IndexDefinition
  397. {
  398. Map = "from doc in docs.Images select new { doc.Name }",
  399. Indexes = {
  400. { "Name", FieldIndexing.Analyzed }
  401. }
  402. });
  403. using (var session = store.OpenSession())
  404. {
  405. var images = session.Query<Image>("test")
  406. .Customize(x => x.WaitForNonStaleResults())
  407. .OrderBy(x => x.Name)
  408. .Search(x => x.Name, "Photo", options: SearchOptions.And)
  409. .Where(x => x.Id == "1")
  410. .ToList();
  411. WaitForUserToContinueTheTest(store);
  412. Assert.NotEmpty(images);
  413. Assert.True(images.Count == 1);
  414. }
  415. }
  416. }
  417. [Fact]
  418. public void Can_have_special_characters_in_search_text()
  419. {
  420. const string specialCharacters = "+-!(){}:[]^\"~*";
  421. using (var store = NewDocumentStore())
  422. {
  423. using (var session = store.OpenSession())
  424. {
  425. foreach (var specialCharacter in specialCharacters)
  426. {
  427. var qry = session.Query<Image>()
  428. .Customize(x => x.WaitForNonStaleResults())
  429. .Search(x => x.Name, specialCharacter.ToString());
  430. Assert.Equal(string.Format("Name:(\\{0})", specialCharacter), qry.ToString());
  431. qry.ToList();
  432. }
  433. }
  434. }
  435. }
  436. [Fact]
  437. public void Can_have_special_characters_in_search_text_string()
  438. {
  439. using (var store = NewDocumentStore())
  440. {
  441. using (var session = store.OpenSession())
  442. {
  443. var qry = session.Query<Image>()
  444. .Customize(x => x.WaitForNonStaleResults())
  445. .Search(x => x.Name, "He said: hello there");
  446. Assert.Equal("Name:(He said\\: hello there)", qry.ToString());
  447. qry.ToList();
  448. }
  449. }
  450. }
  451. }
  452. }