|
7 | 7 | */ |
8 | 8 | package org.dspace.browse; |
9 | 9 |
|
10 | | -import java.util.HashMap; |
11 | | -import java.util.List; |
12 | | -import java.util.Map; |
13 | | - |
| 10 | +import org.apache.logging.log4j.LogManager; |
14 | 11 | import org.apache.logging.log4j.Logger; |
| 12 | +import org.apache.solr.client.solrj.SolrClient; |
| 13 | +import org.apache.solr.client.solrj.SolrQuery; |
| 14 | +import org.apache.solr.client.solrj.response.QueryResponse; |
15 | 15 | import org.dspace.content.Collection; |
16 | 16 | import org.dspace.content.Community; |
17 | 17 | import org.dspace.content.DSpaceObject; |
18 | 18 | import org.dspace.core.Context; |
19 | | -import org.dspace.discovery.DiscoverFacetField; |
20 | | -import org.dspace.discovery.DiscoverQuery; |
21 | | -import org.dspace.discovery.DiscoverResult; |
22 | | -import org.dspace.discovery.DiscoverResult.FacetResult; |
23 | | -import org.dspace.discovery.SearchService; |
24 | | -import org.dspace.discovery.SearchServiceException; |
25 | | -import org.dspace.discovery.configuration.DiscoveryConfigurationParameters; |
| 19 | +import org.dspace.discovery.SolrSearchCore; |
26 | 20 | import org.dspace.discovery.indexobject.IndexableItem; |
27 | 21 | import org.springframework.beans.factory.annotation.Autowired; |
28 | 22 |
|
29 | 23 | /** |
30 | 24 | * Discovery (Solr) driver implementing ItemCountDAO interface to look up item |
31 | | - * count information in communities and collections. Caching operations are |
32 | | - * intentionally not implemented because Solr already is our cache. |
| 25 | + * count information in communities and collections. |
| 26 | + * <p> |
| 27 | + * Counts are computed by querying Solr for archived, non-withdrawn, discoverable |
| 28 | + * items using {@code location.comm} / {@code location.coll} filters. |
| 29 | + * The query returns only {@code numFound} (rows=0), making it very fast. |
33 | 30 | */ |
34 | 31 | public class ItemCountDAOSolr implements ItemCountDAO { |
35 | | - /** |
36 | | - * Log4j logger |
37 | | - */ |
38 | | - private static Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemCountDAOSolr.class); |
39 | | - |
40 | | - /** |
41 | | - * Hold the communities item count obtained from SOLR after the first query. This only works |
42 | | - * well if the ItemCountDAO lifecycle is bound to the request lifecycle as |
43 | | - * it is now. If we switch to a Spring-based instantiation we should mark |
44 | | - * this bean as prototype |
45 | | - **/ |
46 | | - private Map<String, Integer> communitiesCount = null; |
47 | | - |
48 | | - /** |
49 | | - * Hold the collection item count obtained from SOLR after the first query |
50 | | - **/ |
51 | | - private Map<String, Integer> collectionsCount = null; |
52 | 32 |
|
| 33 | + private static final Logger log = LogManager.getLogger(ItemCountDAOSolr.class); |
53 | 34 |
|
54 | | - /** |
55 | | - * Solr search service |
56 | | - */ |
57 | 35 | @Autowired |
58 | | - protected SearchService searchService; |
| 36 | + private SolrSearchCore solrSearchCore; |
59 | 37 |
|
60 | | - /** |
61 | | - * Get the count of the items in the given container. |
62 | | - * |
63 | | - * @param context DSpace context |
64 | | - * @param dso DspaceObject |
65 | | - * @return count |
66 | | - */ |
67 | 38 | @Override |
68 | 39 | public int getCount(Context context, DSpaceObject dso) { |
69 | | - loadCount(context); |
70 | | - Integer val = null; |
| 40 | + String locationFilter; |
71 | 41 | if (dso instanceof Collection) { |
72 | | - val = collectionsCount.get(dso.getID().toString()); |
| 42 | + locationFilter = "location.coll:" + dso.getID().toString(); |
73 | 43 | } else if (dso instanceof Community) { |
74 | | - val = communitiesCount.get(dso.getID().toString()); |
75 | | - } |
76 | | - |
77 | | - if (val != null) { |
78 | | - return val; |
| 44 | + locationFilter = "location.comm:" + dso.getID().toString(); |
79 | 45 | } else { |
80 | 46 | return 0; |
81 | 47 | } |
82 | | - } |
83 | 48 |
|
84 | | - /** |
85 | | - * make sure that the counts are actually fetched from Solr (if haven't been |
86 | | - * cached in a Map yet) |
87 | | - * |
88 | | - * @param context DSpace Context |
89 | | - */ |
90 | | - private void loadCount(Context context) { |
91 | | - if (communitiesCount != null || collectionsCount != null) { |
92 | | - return; |
93 | | - } |
94 | | - |
95 | | - communitiesCount = new HashMap<>(); |
96 | | - collectionsCount = new HashMap<>(); |
97 | | - |
98 | | - DiscoverQuery query = new DiscoverQuery(); |
99 | | - query.setFacetMinCount(1); |
100 | | - query.addFacetField(new DiscoverFacetField("location.comm", |
101 | | - DiscoveryConfigurationParameters.TYPE_STANDARD, -1, |
102 | | - DiscoveryConfigurationParameters.SORT.COUNT)); |
103 | | - query.addFacetField(new DiscoverFacetField("location.coll", |
104 | | - DiscoveryConfigurationParameters.TYPE_STANDARD, -1, |
105 | | - DiscoveryConfigurationParameters.SORT.COUNT)); |
106 | | - query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE); // count only items |
107 | | - query.addFilterQueries("NOT(discoverable:false)"); // only discoverable |
108 | | - query.addFilterQueries("withdrawn:false"); // only not withdrawn |
109 | | - query.addFilterQueries("archived:true"); // only archived |
110 | | - query.setMaxResults(0); |
111 | | - |
112 | | - DiscoverResult sResponse; |
113 | 49 | try { |
114 | | - sResponse = searchService.search(context, query); |
115 | | - List<FacetResult> commCount = sResponse.getFacetResult("location.comm"); |
116 | | - List<FacetResult> collCount = sResponse.getFacetResult("location.coll"); |
117 | | - for (FacetResult c : commCount) { |
118 | | - communitiesCount.put(c.getAsFilterQuery(), (int) c.getCount()); |
119 | | - } |
120 | | - for (FacetResult c : collCount) { |
121 | | - collectionsCount.put(c.getAsFilterQuery(), (int) c.getCount()); |
| 50 | + SolrClient solr = solrSearchCore.getSolr(); |
| 51 | + if (solr == null) { |
| 52 | + return 0; |
122 | 53 | } |
123 | | - } catch (SearchServiceException e) { |
124 | | - log.error("Could not initialize Community/Collection Item Counts from Solr: ", e); |
| 54 | + SolrQuery query = new SolrQuery("*:*"); |
| 55 | + query.addFilterQuery(locationFilter); |
| 56 | + query.addFilterQuery("search.resourcetype:" + IndexableItem.TYPE); |
| 57 | + query.addFilterQuery("NOT(discoverable:false)"); |
| 58 | + query.addFilterQuery("withdrawn:false"); |
| 59 | + query.addFilterQuery("archived:true"); |
| 60 | + query.setRows(0); |
| 61 | + QueryResponse response = solr.query(query, solrSearchCore.REQUEST_METHOD); |
| 62 | + return (int) response.getResults().getNumFound(); |
| 63 | + } catch (Exception e) { |
| 64 | + log.error("Error counting items in Solr for {}: ", dso.getID(), e); |
125 | 65 | } |
| 66 | + return 0; |
126 | 67 | } |
127 | 68 | } |
0 commit comments