@@ -77,6 +77,8 @@ public class SolrQueryLayerService extends SolrSearchService {
77
77
protected SearchStateFactory searchStateFactory ;
78
78
protected PID collectionsPid ;
79
79
protected ObjectPathFactory pathFactory ;
80
+
81
+ private static int NEIGHBOR_SEEK_PAGE_SIZE = 500 ;
80
82
81
83
/**
82
84
* Returns a list of the most recently added items in the collection
@@ -286,10 +288,9 @@ public List<BriefObjectMetadataBean> getParentCollectionValues(FacetFieldObject
286
288
}
287
289
288
290
/**
289
- * Retrieves a list of the nearest windowSize neighbors within the nearest parent collection or folder around the
290
- * item metadata, based on the order field of the item. The first windowSize - 1 neighbors are retrieved to each side
291
- * of the item, and trimmed so that there are always windowSize - 1 neighbors surrounding the item if possible. If no
292
- * order field is available, a list of arbitrary windowSize neighbors is returned.
291
+ * Retrieves a list of the closest windowSize neighbors within the parent container of the specified object,
292
+ * using the default sort order. The first windowSize / 2 - 1 neighbors are retrieved to each side
293
+ * of the item, and trimmed so that there are always windowSize - 1 neighbors surrounding the item if possible.
293
294
*
294
295
* @param metadata
295
296
* Record which the window pivots around.
@@ -303,187 +304,98 @@ public List<BriefObjectMetadataBean> getNeighboringItems(BriefObjectMetadataBean
303
304
AccessGroupSet accessGroups ) {
304
305
305
306
// Get the common access restriction clause (starts with "AND ...")
306
-
307
307
StringBuilder accessRestrictionClause = new StringBuilder ();
308
308
309
309
try {
310
310
addAccessRestrictions (accessRestrictionClause , accessGroups );
311
311
} catch (AccessRestrictionException e ) {
312
312
// If the user doesn't have any access groups, they don't have access to anything, return null.
313
- LOG .error (e . getMessage () );
313
+ LOG .error ("Attempted to get neighboring items without creditentials" , e );
314
314
return null ;
315
315
}
316
316
317
- // Prepare the common query object, including a filter for resource type and the
318
- // facet which selects only the item's siblings.
319
-
317
+ // Restrict query to files/aggregates and objects within the same parent
320
318
SolrQuery solrQuery = new SolrQuery ();
319
+ solrQuery .setQuery ("*:*" + accessRestrictionClause );
321
320
322
321
solrQuery .setFacet (true );
323
322
solrQuery .addFilterQuery (solrSettings .getFieldName (SearchFieldKeys .RESOURCE_TYPE .name ()) + ":File "
324
323
+ solrSettings .getFieldName (SearchFieldKeys .RESOURCE_TYPE .name ()) + ":Aggregate" );
325
324
326
325
CutoffFacet ancestorPath = null ;
327
-
328
326
if (metadata .getResourceType ().equals (searchSettings .resourceTypeFile )
329
327
|| metadata .getResourceType ().equals (searchSettings .resourceTypeAggregate )) {
330
328
ancestorPath = metadata .getAncestorPathFacet ();
331
329
} else {
332
330
ancestorPath = metadata .getPath ();
333
331
}
334
-
335
332
if (ancestorPath != null ) {
336
333
// We want only objects at the same level of the hierarchy
337
334
ancestorPath .setCutoff (ancestorPath .getHighestTier () + 1 );
338
335
339
336
facetFieldUtil .addToSolrQuery (ancestorPath , solrQuery );
340
337
}
341
-
342
- // If this item has no display order, get arbitrary items surrounding it.
343
-
344
- Long pivotOrder = metadata .getDisplayOrder ();
345
-
346
- if (pivotOrder == null ) {
347
-
348
- LOG .debug ("No display order, just querying for " + windowSize + " siblings" );
349
-
350
- StringBuilder query = new StringBuilder ();
351
-
352
- List <BriefObjectMetadataBean > list = null ;
353
-
354
- query .append ("*:*" );
355
- query .append (accessRestrictionClause );
356
- solrQuery .setQuery (query .toString ());
357
-
358
- solrQuery .setStart (0 );
359
- solrQuery .setRows (windowSize );
360
-
361
- solrQuery .setSort (solrSettings .getFieldName (SearchFieldKeys .DISPLAY_ORDER .name ()), SolrQuery .ORDER .desc );
362
-
363
- try {
364
- QueryResponse queryResponse = this .executeQuery (solrQuery );
365
- list = queryResponse .getBeans (BriefObjectMetadataBean .class );
366
- } catch (SolrServerException e ) {
367
- LOG .error ("Error retrieving Neighboring items: " + e );
368
- return null ;
369
- }
370
-
371
- return list ;
372
-
373
- // Otherwise, query for items surrounding this item.
374
-
375
- } else {
376
-
377
- LOG .debug ("Display order is " + pivotOrder );
378
-
379
- // Find the right and left lists
380
-
381
- StringBuilder query ;
382
-
383
- List <BriefObjectMetadataBean > leftList = null ;
384
- List <BriefObjectMetadataBean > rightList = null ;
385
-
386
- solrQuery .setStart (0 );
387
- solrQuery .setRows (windowSize - 1 );
388
-
389
- // Right list
390
-
391
- query = new StringBuilder ();
392
-
393
- query .append (solrSettings .getFieldName (SearchFieldKeys .DISPLAY_ORDER .name ())).append (":[" )
394
- .append (pivotOrder + 1 ).append (" TO *]" );
395
- query .append (accessRestrictionClause );
396
- solrQuery .setQuery (query .toString ());
397
-
398
- solrQuery .setSort (solrSettings .getFieldName (SearchFieldKeys .DISPLAY_ORDER .name ()), SolrQuery .ORDER .asc );
399
-
400
- try {
401
- QueryResponse queryResponse = this .executeQuery (solrQuery );
402
- rightList = queryResponse .getBeans (BriefObjectMetadataBean .class );
403
- } catch (SolrServerException e ) {
404
- LOG .error ("Error retrieving Neighboring items: " + e );
405
- return null ;
406
- }
407
-
408
- LOG .debug ("Got " + rightList .size () + " items for right list" );
409
-
410
- // Left list
411
-
412
- // (Note that display order stuff is reversed.)
413
-
414
- query = new StringBuilder ();
415
-
416
- query .append (solrSettings .getFieldName (SearchFieldKeys .DISPLAY_ORDER .name ())).append (":[* TO " )
417
- .append (pivotOrder - 1 ).append ("]" );
418
- query .append (accessRestrictionClause );
419
- solrQuery .setQuery (query .toString ());
420
-
421
- solrQuery .setSort (solrSettings .getFieldName (SearchFieldKeys .DISPLAY_ORDER .name ()), SolrQuery .ORDER .desc );
422
-
338
+
339
+ // Sort neighbors using the default sort
340
+ addSort (solrQuery , "default" , true );
341
+
342
+
343
+ // Query for ids in this container in groups of NEIGHBOR_SEEK_PAGE_SIZE until we find the offset of the object
344
+ solrQuery .setRows (NEIGHBOR_SEEK_PAGE_SIZE );
345
+ solrQuery .setFields ("id" );
346
+
347
+ long total = -1 ;
348
+ int start = 0 ;
349
+ pageLoop : do {
423
350
try {
351
+ solrQuery .setStart (start );
424
352
QueryResponse queryResponse = this .executeQuery (solrQuery );
425
- leftList = queryResponse .getBeans (BriefObjectMetadataBean .class );
353
+ total = queryResponse .getResults ().getNumFound ();
354
+ for (SolrDocument doc : queryResponse .getResults ()) {
355
+ if (metadata .getId ().equals (doc .getFieldValue ("id" ))) {
356
+ break pageLoop ;
357
+ }
358
+ start ++;
359
+ }
426
360
} catch (SolrServerException e ) {
427
361
LOG .error ("Error retrieving Neighboring items: " + e );
428
362
return null ;
429
363
}
430
-
431
- LOG .debug ("Got " + leftList .size () + " items for left list" );
432
-
433
- // Trim the lists
434
-
435
- int halfWindow = windowSize / 2 ;
436
-
437
- // If we have enough in both lists, trim both to be
438
- // halfWindow long.
439
-
440
- if (leftList .size () >= halfWindow && rightList .size () >= halfWindow ) {
441
-
442
- LOG .debug ("Trimming both lists" );
443
-
444
- leftList .subList (halfWindow , leftList .size ()).clear ();
445
- rightList .subList (halfWindow , rightList .size ()).clear ();
446
-
447
- // If we don't have enough in the left list and we have extra in the right list,
448
- // try to pick up the slack by trimming fewer items from the right list.
449
-
450
- } else if (leftList .size () < halfWindow && rightList .size () > halfWindow ) {
451
-
452
- LOG .debug ("Picking up slack from right list" );
453
-
454
- // How much extra do we need from the right list?
455
-
456
- int extra = halfWindow - leftList .size ();
457
-
458
- // Only "take" the extra (ie, clear less of the right list) if we have it available.
459
-
460
- if (halfWindow + extra < rightList .size ())
461
- rightList .subList (halfWindow + extra , rightList .size ()).clear ();
462
-
463
- } else if (rightList .size () < halfWindow && leftList .size () > halfWindow ) {
464
-
465
- LOG .debug ("Picking up slack from left list" );
466
-
467
- int extra = halfWindow - rightList .size ();
468
-
469
- if (halfWindow + extra < leftList .size ())
470
- leftList .subList (halfWindow + extra , leftList .size ()).clear ();
471
-
364
+ } while (start < total );
365
+
366
+ // Wasn't found, no neighbors shall be forthcoming
367
+ if (start >= total ) {
368
+ return null ;
369
+ }
370
+
371
+ // Calculate the starting index for the window, so that object is as close to the middle as possible
372
+ long left = start - (windowSize / 2 );
373
+ long right = start + (windowSize / 2 );
374
+
375
+ if (left < 0 ) {
376
+ right -= left ;
377
+ left = 0 ;
378
+ }
379
+
380
+ if (right >= total ) {
381
+ left -= (right - total ) + 1 ;
382
+ if (left < 0 ) {
383
+ left = 0 ;
472
384
}
473
-
474
- // (Otherwise, we do no trimming, since both lists are smaller or the same size
475
- // as the window.)
476
-
477
- // Assemble the result.
478
-
479
- Collections .reverse (leftList );
480
- leftList .add (metadata );
481
- leftList .addAll (rightList );
482
-
483
- return leftList ;
484
-
485
385
}
486
-
386
+
387
+ // Query for the windowSize of objects
388
+ solrQuery .setFields (new String [0 ]);
389
+ solrQuery .setRows (windowSize );
390
+ solrQuery .setStart ((int ) left );
391
+
392
+ try {
393
+ QueryResponse queryResponse = this .executeQuery (solrQuery );
394
+ return queryResponse .getBeans (BriefObjectMetadataBean .class );
395
+ } catch (SolrServerException e ) {
396
+ LOG .error ("Error retrieving Neighboring items: " + e );
397
+ return null ;
398
+ }
487
399
}
488
400
489
401
/**
0 commit comments