1 package org.apache.lucene.search; 2 3 18 19 import org.apache.lucene.store.RAMDirectory; 20 import org.apache.lucene.index.*; 21 import org.apache.lucene.analysis.SimpleAnalyzer; 22 import org.apache.lucene.document.Document; 23 import org.apache.lucene.document.Field; 24 25 import java.rmi.Naming ; 26 import java.rmi.registry.LocateRegistry ; 27 import java.rmi.registry.Registry ; 28 import java.io.IOException ; 29 import java.io.Serializable ; 30 import java.util.regex.Pattern ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 import java.util.Locale ; 34 35 import junit.framework.TestCase; 36 import junit.framework.Test; 37 import junit.framework.TestSuite; 38 import junit.textui.TestRunner; 39 40 49 50 public class TestSort 51 extends TestCase 52 implements Serializable { 53 54 private Searcher full; 55 private Searcher searchX; 56 private Searcher searchY; 57 private Query queryX; 58 private Query queryY; 59 private Query queryA; 60 private Query queryF; 61 private Sort sort; 62 63 64 public TestSort (String name) { 65 super (name); 66 } 67 68 public static void main (String [] argv) { 69 if (argv == null || argv.length < 1) 70 TestRunner.run (suite()); 71 else if ("server".equals (argv[0])) { 72 TestSort test = new TestSort (null); 73 try { 74 test.startServer(); 75 Thread.sleep (500000); 76 } catch (Exception e) { 77 System.out.println (e); 78 e.printStackTrace(); 79 } 80 } 81 } 82 83 public static Test suite() { 84 return new TestSuite (TestSort.class); 85 } 86 87 88 private String [][] data = new String [][] { 95 { "A", "x a", "5", "4f", "c", "A-3" }, 97 { "B", "y a", "5", "3.4028235E38", "i", "B-10" }, 98 { "C", "x a b c", "2147483647", "1.0", "j", "A-2" }, 99 { "D", "y a b c", "-1", "0.0f", "a", "C-0" }, 100 { "E", "x a b c d", "5", "2f", "h", "B-8" }, 101 { "F", "y a b c d", "2", "3.14159f", "g", "B-1" }, 102 { "G", "x a b c d", "3", "-1.0", "f", "C-100" }, 103 { "H", "y a b c d", "0", "1.4E-45", "e", "C-88" }, 104 { "I", "x a b c d e f", "-2147483648", "1.0e+0", "d", "A-10" }, 105 { "J", "y a b c d e f", "4", ".5", "b", "C-7" }, 106 { "Z", "f", null, null, null, null } 107 }; 108 109 private Searcher getIndex (boolean even, boolean odd) 111 throws IOException { 112 RAMDirectory indexStore = new RAMDirectory (); 113 IndexWriter writer = new IndexWriter (indexStore, new SimpleAnalyzer(), true); 114 for (int i=0; i<data.length; ++i) { 115 if (((i%2)==0 && even) || ((i%2)==1 && odd)) { 116 Document doc = new Document(); doc.add (new Field ("tracer", data[i][0], true, false, false)); 118 doc.add (new Field ("contents", data[i][1], false, true, true)); 119 if (data[i][2] != null) doc.add (new Field ("int", data[i][2], false, true, false)); 120 if (data[i][3] != null) doc.add (new Field ("float", data[i][3], false, true, false)); 121 if (data[i][4] != null) doc.add (new Field ("string", data[i][4], false, true, false)); 122 if (data[i][5] != null) doc.add (new Field ("custom", data[i][5], false, true, false)); 123 writer.addDocument (doc); 124 } 125 } 126 writer.optimize (); 127 writer.close (); 128 return new IndexSearcher (indexStore); 129 } 130 131 private Searcher getFullIndex() 132 throws IOException { 133 return getIndex (true, true); 134 } 135 136 private Searcher getXIndex() 137 throws IOException { 138 return getIndex (true, false); 139 } 140 141 private Searcher getYIndex() 142 throws IOException { 143 return getIndex (false, true); 144 } 145 146 private Searcher getEmptyIndex() 147 throws IOException { 148 return getIndex (false, false); 149 } 150 151 public void setUp() throws Exception { 152 full = getFullIndex(); 153 searchX = getXIndex(); 154 searchY = getYIndex(); 155 queryX = new TermQuery (new Term ("contents", "x")); 156 queryY = new TermQuery (new Term ("contents", "y")); 157 queryA = new TermQuery (new Term ("contents", "a")); 158 queryF = new TermQuery (new Term ("contents", "f")); 159 sort = new Sort(); 160 } 161 162 public void testBuiltInSorts() throws Exception { 164 sort = new Sort(); 165 assertMatches (full, queryX, sort, "ACEGI"); 166 assertMatches (full, queryY, sort, "BDFHJ"); 167 168 sort.setSort(SortField.FIELD_DOC); 169 assertMatches (full, queryX, sort, "ACEGI"); 170 assertMatches (full, queryY, sort, "BDFHJ"); 171 } 172 173 public void testTypedSort() throws Exception { 175 sort.setSort (new SortField[] { new SortField ("int", SortField.INT), SortField.FIELD_DOC }); 176 assertMatches (full, queryX, sort, "IGAEC"); 177 assertMatches (full, queryY, sort, "DHFJB"); 178 179 sort.setSort (new SortField[] { new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC }); 180 assertMatches (full, queryX, sort, "GCIEA"); 181 assertMatches (full, queryY, sort, "DHJFB"); 182 183 sort.setSort (new SortField[] { new SortField ("string", SortField.STRING), SortField.FIELD_DOC }); 184 assertMatches (full, queryX, sort, "AIGEC"); 185 assertMatches (full, queryY, sort, "DJHFB"); 186 } 187 188 public void testEmptyIndex() throws Exception { 190 Searcher empty = getEmptyIndex(); 191 192 sort = new Sort(); 193 assertMatches (empty, queryX, sort, ""); 194 195 sort.setSort(SortField.FIELD_DOC); 196 assertMatches (empty, queryX, sort, ""); 197 198 sort.setSort (new SortField[] { new SortField ("int", SortField.INT), SortField.FIELD_DOC }); 199 assertMatches (empty, queryX, sort, ""); 200 201 sort.setSort (new SortField[] { new SortField ("string", SortField.STRING, true), SortField.FIELD_DOC }); 202 assertMatches (empty, queryX, sort, ""); 203 204 sort.setSort (new SortField[] { new SortField ("float", SortField.FLOAT), new SortField ("string", SortField.STRING) }); 205 assertMatches (empty, queryX, sort, ""); 206 } 207 208 public void testAutoSort() throws Exception { 210 sort.setSort("int"); 211 assertMatches (full, queryX, sort, "IGAEC"); 212 assertMatches (full, queryY, sort, "DHFJB"); 213 214 sort.setSort("float"); 215 assertMatches (full, queryX, sort, "GCIEA"); 216 assertMatches (full, queryY, sort, "DHJFB"); 217 218 sort.setSort("string"); 219 assertMatches (full, queryX, sort, "AIGEC"); 220 assertMatches (full, queryY, sort, "DJHFB"); 221 } 222 223 public void testReverseSort() throws Exception { 225 sort.setSort (new SortField[] { new SortField (null, SortField.SCORE, true), SortField.FIELD_DOC }); 226 assertMatches (full, queryX, sort, "IEGCA"); 227 assertMatches (full, queryY, sort, "JFHDB"); 228 229 sort.setSort (new SortField (null, SortField.DOC, true)); 230 assertMatches (full, queryX, sort, "IGECA"); 231 assertMatches (full, queryY, sort, "JHFDB"); 232 233 sort.setSort ("int", true); 234 assertMatches (full, queryX, sort, "CAEGI"); 235 assertMatches (full, queryY, sort, "BJFHD"); 236 237 sort.setSort ("float", true); 238 assertMatches (full, queryX, sort, "AECIG"); 239 assertMatches (full, queryY, sort, "BFJHD"); 240 241 sort.setSort ("string", true); 242 assertMatches (full, queryX, sort, "CEGIA"); 243 assertMatches (full, queryY, sort, "BFHJD"); 244 } 245 246 public void testEmptyFieldSort() throws Exception { 248 sort.setSort ("string"); 249 assertMatches (full, queryF, sort, "ZJI"); 250 251 sort.setSort ("string", true); 252 assertMatches (full, queryF, sort, "IJZ"); 253 254 sort.setSort ("int"); 255 assertMatches (full, queryF, sort, "IZJ"); 256 257 sort.setSort ("int", true); 258 assertMatches (full, queryF, sort, "JZI"); 259 260 sort.setSort ("float"); 261 assertMatches (full, queryF, sort, "ZJI"); 262 263 sort.setSort ("float", true); 264 assertMatches (full, queryF, sort, "IJZ"); 265 } 266 267 public void testSortCombos() throws Exception { 269 sort.setSort (new String [] {"int","float"}); 270 assertMatches (full, queryX, sort, "IGEAC"); 271 272 sort.setSort (new SortField[] { new SortField ("int", true), new SortField (null, SortField.DOC, true) }); 273 assertMatches (full, queryX, sort, "CEAGI"); 274 275 sort.setSort (new String [] {"float","string"}); 276 assertMatches (full, queryX, sort, "GICEA"); 277 } 278 279 public void testLocaleSort() throws Exception { 281 sort.setSort (new SortField[] { new SortField ("string", Locale.US) }); 282 assertMatches (full, queryX, sort, "AIGEC"); 283 assertMatches (full, queryY, sort, "DJHFB"); 284 285 sort.setSort (new SortField[] { new SortField ("string", Locale.US, true) }); 286 assertMatches (full, queryX, sort, "CEGIA"); 287 assertMatches (full, queryY, sort, "BFHJD"); 288 } 289 290 public void testCustomSorts() throws Exception { 292 sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource())); 293 assertMatches (full, queryX, sort, "CAIEG"); 294 sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource(), true)); 295 assertMatches (full, queryY, sort, "HJDBF"); 296 SortComparator custom = SampleComparable.getComparator(); 297 sort.setSort (new SortField ("custom", custom)); 298 assertMatches (full, queryX, sort, "CAIEG"); 299 sort.setSort (new SortField ("custom", custom, true)); 300 assertMatches (full, queryY, sort, "HJDBF"); 301 } 302 303 public void testMultiSort() throws Exception { 305 MultiSearcher searcher = new MultiSearcher (new Searchable[] { searchX, searchY }); 306 runMultiSorts (searcher); 307 } 308 309 public void testParallelMultiSort() throws Exception { 311 Searcher searcher = new ParallelMultiSearcher (new Searchable[] { searchX, searchY }); 312 runMultiSorts (searcher); 313 } 314 315 public void testRemoteSort() throws Exception { 317 Searchable searcher = getRemote(); 318 MultiSearcher multi = new MultiSearcher (new Searchable[] { searcher }); 319 runMultiSorts (multi); 320 } 321 322 public void testRemoteCustomSort() throws Exception { 324 Searchable searcher = getRemote(); 325 MultiSearcher multi = new MultiSearcher (new Searchable[] { searcher }); 326 sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource())); 327 assertMatches (multi, queryX, sort, "CAIEG"); 328 sort.setSort (new SortField ("custom", SampleComparable.getComparatorSource(), true)); 329 assertMatches (multi, queryY, sort, "HJDBF"); 330 SortComparator custom = SampleComparable.getComparator(); 331 sort.setSort (new SortField ("custom", custom)); 332 assertMatches (multi, queryX, sort, "CAIEG"); 333 sort.setSort (new SortField ("custom", custom, true)); 334 assertMatches (multi, queryY, sort, "HJDBF"); 335 } 336 337 public void testNormalizedScores() throws Exception { 340 341 HashMap scoresX = getScores (full.search (queryX)); 343 HashMap scoresY = getScores (full.search (queryY)); 344 HashMap scoresA = getScores (full.search (queryA)); 345 346 MultiSearcher remote = new MultiSearcher (new Searchable[] { getRemote() }); 352 MultiSearcher multi = new MultiSearcher (new Searchable[] { full, full }); 353 354 356 sort = new Sort(); 357 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 358 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 359 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 360 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 361 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 362 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 363 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 364 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 365 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 366 367 sort.setSort(SortField.FIELD_DOC); 368 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 369 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 370 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 371 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 372 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 373 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 374 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 375 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 376 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 377 378 sort.setSort ("int"); 379 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 380 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 381 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 382 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 383 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 384 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 385 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 386 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 387 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 388 389 sort.setSort ("float"); 390 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 391 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 392 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 393 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 394 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 395 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 396 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 397 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 398 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 399 400 sort.setSort ("string"); 401 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 402 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 403 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 404 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 405 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 406 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 407 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 408 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 409 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 410 411 sort.setSort (new String [] {"int","float"}); 412 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 413 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 414 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 415 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 416 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 417 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 418 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 419 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 420 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 421 422 sort.setSort (new SortField[] { new SortField ("int", true), new SortField (null, SortField.DOC, true) }); 423 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 424 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 425 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 426 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 427 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 428 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 429 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 430 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 431 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 432 433 sort.setSort (new String [] {"float","string"}); 434 assertSameValues (scoresX, getScores(full.search(queryX,sort))); 435 assertSameValues (scoresX, getScores(remote.search(queryX,sort))); 436 assertSameValues (scoresX, getScores(multi.search(queryX,sort))); 437 assertSameValues (scoresY, getScores(full.search(queryY,sort))); 438 assertSameValues (scoresY, getScores(remote.search(queryY,sort))); 439 assertSameValues (scoresY, getScores(multi.search(queryY,sort))); 440 assertSameValues (scoresA, getScores(full.search(queryA,sort))); 441 assertSameValues (scoresA, getScores(remote.search(queryA,sort))); 442 assertSameValues (scoresA, getScores(multi.search(queryA,sort))); 443 444 } 445 446 private void runMultiSorts (Searcher multi) throws Exception { 448 sort.setSort (SortField.FIELD_DOC); 449 assertMatchesPattern (multi, queryA, sort, "[AB]{2}[CD]{2}[EF]{2}[GH]{2}[IJ]{2}"); 450 451 sort.setSort (new SortField ("int", SortField.INT)); 452 assertMatchesPattern (multi, queryA, sort, "IDHFGJ[ABE]{3}C"); 453 454 sort.setSort (new SortField[] {new SortField ("int", SortField.INT), SortField.FIELD_DOC}); 455 assertMatchesPattern (multi, queryA, sort, "IDHFGJ[AB]{2}EC"); 456 457 sort.setSort ("int"); 458 assertMatchesPattern (multi, queryA, sort, "IDHFGJ[AB]{2}EC"); 459 460 sort.setSort (new SortField[] {new SortField ("float", SortField.FLOAT), SortField.FIELD_DOC}); 461 assertMatchesPattern (multi, queryA, sort, "GDHJ[CI]{2}EFAB"); 462 463 sort.setSort ("float"); 464 assertMatchesPattern (multi, queryA, sort, "GDHJ[CI]{2}EFAB"); 465 466 sort.setSort ("string"); 467 assertMatches (multi, queryA, sort, "DJAIHGFEBC"); 468 469 sort.setSort ("int", true); 470 assertMatchesPattern (multi, queryA, sort, "C[AB]{2}EJGFHDI"); 471 472 sort.setSort ("float", true); 473 assertMatchesPattern (multi, queryA, sort, "BAFE[IC]{2}JHDG"); 474 475 sort.setSort ("string", true); 476 assertMatches (multi, queryA, sort, "CBEFGHIAJD"); 477 478 sort.setSort (new SortField[] { new SortField ("string", Locale.US) }); 479 assertMatches (multi, queryA, sort, "DJAIHGFEBC"); 480 481 sort.setSort (new SortField[] { new SortField ("string", Locale.US, true) }); 482 assertMatches (multi, queryA, sort, "CBEFGHIAJD"); 483 484 sort.setSort (new String [] {"int","float"}); 485 assertMatches (multi, queryA, sort, "IDHFGJEABC"); 486 487 sort.setSort (new String [] {"float","string"}); 488 assertMatches (multi, queryA, sort, "GDHJICEFAB"); 489 490 sort.setSort ("int"); 491 assertMatches (multi, queryF, sort, "IZJ"); 492 493 sort.setSort ("int", true); 494 assertMatches (multi, queryF, sort, "JZI"); 495 496 sort.setSort ("float"); 497 assertMatches (multi, queryF, sort, "ZJI"); 498 499 sort.setSort ("string"); 500 assertMatches (multi, queryF, sort, "ZJI"); 501 502 sort.setSort ("string", true); 503 assertMatches (multi, queryF, sort, "IJZ"); 504 } 505 506 private void assertMatches (Searcher searcher, Query query, Sort sort, String expectedResult) 508 throws IOException { 509 Hits result = searcher.search (query, sort); 510 StringBuffer buff = new StringBuffer (10); 511 int n = result.length(); 512 for (int i=0; i<n; ++i) { 513 Document doc = result.doc(i); 514 String [] v = doc.getValues("tracer"); 515 for (int j=0; j<v.length; ++j) { 516 buff.append (v[j]); 517 } 518 } 519 assertEquals (expectedResult, buff.toString()); 520 } 521 522 private void assertMatchesPattern (Searcher searcher, Query query, Sort sort, String pattern) 524 throws IOException { 525 Hits result = searcher.search (query, sort); 526 StringBuffer buff = new StringBuffer (10); 527 int n = result.length(); 528 for (int i=0; i<n; ++i) { 529 Document doc = result.doc(i); 530 String [] v = doc.getValues("tracer"); 531 for (int j=0; j<v.length; ++j) { 532 buff.append (v[j]); 533 } 534 } 535 assertTrue (Pattern.compile(pattern).matcher(buff.toString()).matches()); 537 } 538 539 private HashMap getScores (Hits hits) 540 throws IOException { 541 HashMap scoreMap = new HashMap (); 542 int n = hits.length(); 543 for (int i=0; i<n; ++i) { 544 Document doc = hits.doc(i); 545 String [] v = doc.getValues("tracer"); 546 assertEquals (v.length, 1); 547 scoreMap.put (v[0], new Float (hits.score(i))); 548 } 549 return scoreMap; 550 } 551 552 private void assertSameValues (HashMap m1, HashMap m2) { 554 int n = m1.size(); 555 int m = m2.size(); 556 assertEquals (n, m); 557 Iterator iter = m1.keySet().iterator(); 558 while (iter.hasNext()) { 559 Object key = iter.next(); 560 assertEquals (m1.get(key), m2.get(key)); 561 } 562 } 563 564 private Searchable getRemote () throws Exception { 565 try { 566 return lookupRemote (); 567 } catch (Throwable e) { 568 startServer (); 569 return lookupRemote (); 570 } 571 } 572 573 private Searchable lookupRemote () throws Exception { 574 return (Searchable) Naming.lookup ("//localhost/SortedSearchable"); 575 } 576 577 private void startServer () throws Exception { 578 Searcher local = getFullIndex(); 580 582 Registry reg = LocateRegistry.createRegistry (1099); 584 RemoteSearchable impl = new RemoteSearchable (local); 585 Naming.rebind ("//localhost/SortedSearchable", impl); 586 } 587 588 } 589 | Popular Tags |