Skip to content

Commit

Permalink
feat(consortium): Add new facets for shared/local flag and tenantId
Browse files Browse the repository at this point in the history
- update elastic mappings
- add `subjects` option for facet request

Closes: MSEARCH-534
  • Loading branch information
psmagin committed Sep 8, 2023
1 parent 6c8cc60 commit 2c8befd
Show file tree
Hide file tree
Showing 25 changed files with 345 additions and 208 deletions.
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Requires `identifier-types v1.0`
* Requires `call-number-types v1.0`
* Provides `indices v0.6`
* Provides `search v1.1`
* Provides `search v1.2`
* Provides `browse v1.2`

### Features
Expand All @@ -22,6 +22,7 @@
* Implement Active Affiliation Context for stream IDs in Consortia Mode ([MSEARCH-576](https://issues.folio.org/browse/MSEARCH-576))
* Restrict central tenant queries to only shared records ([MSEARCH-588](https://issues.folio.org/browse/MSEARCH-588))
* Implement Active Affiliation Context for browsing ([MSEARCH-580](https://issues.folio.org/browse/MSEARCH-580))
* Add new facets for shared/local flag and tenantId ([MSEARCH-534](https://issues.folio.org/browse/MSEARCH-534))

### Bug fixes
* Fix bug when number of titles response is greater than real ([MSEARCH-526](https://issues.folio.org/browse/MSEARCH-526))
Expand Down
56 changes: 35 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,13 +371,13 @@ Consortium feature on module enable is defined by 'centralTenantId' tenant param

### Search API

| METHOD | URL | DESCRIPTION |
|:-------|:------------------------------|:------------------------------------------------------------------------------|
| GET | `/search/instances` | Search by instances and to this instance items and holding-records |
| GET | `/search/authorities` | Search by authority records |
| GET | `/search/{recordType}/facets` | Get facets where recordType could be: instances, authorities, or contributors |
| GET | ~~`/search/instances/ids`~~ | (DEPRECATED) Stream instance ids as JSON or plain text |
| GET | ~~`/search/holdings/ids`~~ | (DEPRECATED) Stream holding record ids as JSON or plain text |
| METHOD | URL | DESCRIPTION |
|:-------|:------------------------------|:-------------------------------------------------------------------------------------|
| GET | `/search/instances` | Search by instances and to this instance items and holding-records |
| GET | `/search/authorities` | Search by authority records |
| GET | `/search/{recordType}/facets` | Get facets where recordType could be: instances, authorities, contributors, subjects |
| GET | ~~`/search/instances/ids`~~ | (DEPRECATED) Stream instance ids as JSON or plain text |
| GET | ~~`/search/holdings/ids`~~ | (DEPRECATED) Stream holding record ids as JSON or plain text |

#### Searching and filtering

Expand Down Expand Up @@ -636,20 +636,22 @@ GET /instances/facets?query=title all book&facet=source:5,discoverySuppress:2

##### Instance facets

| Option | Type | Description |
|:-------------------------|:-------:|:---------------------------------------------------------------------|
| `source` | term | Requests a source facet |
| `instanceTypeId` | term | Requests a type id facet |
| `statusId` | term | Requests a status id facet |
| `instanceFormatIds` | term | Requests a format id facet |
| `modeOfIssuanceId` | term | Requests a mode of issuance id facet |
| `natureOfContentTermIds` | term | Requests a nature of content terms id facet |
| `languages` | term | Requests a language code facet |
| `instanceTags` | term | Requests a tags facet |
| `staffSuppress` | boolean | Requests a staff suppress facet |
| `discoverySuppress` | boolean | Requests a discovery suppress facet |
| `statisticalCodeIds` | term | Requests a statistical code ids facet |
| `statisticalCodes` | term | Requests a statistical code ids from instance, holdings, item facet |
| Option | Type | Description |
|:-------------------------|:-------:|:--------------------------------------------------------------------|
| `source` | term | Requests a source facet |
| `instanceTypeId` | term | Requests a type id facet |
| `statusId` | term | Requests a status id facet |
| `instanceFormatIds` | term | Requests a format id facet |
| `modeOfIssuanceId` | term | Requests a mode of issuance id facet |
| `natureOfContentTermIds` | term | Requests a nature of content terms id facet |
| `languages` | term | Requests a language code facet |
| `instanceTags` | term | Requests a tags facet |
| `staffSuppress` | boolean | Requests a staff suppress facet |
| `discoverySuppress` | boolean | Requests a discovery suppress facet |
| `statisticalCodeIds` | term | Requests a statistical code ids facet |
| `statisticalCodes` | term | Requests a statistical code ids from instance, holdings, item facet |
| `tenantId` | term | Requests a tenantId facet |
| `shared` | term | Requests a shared/local facet |

##### Holdings facets

Expand All @@ -661,6 +663,7 @@ GET /instances/facets?query=title all book&facet=source:5,discoverySuppress:2
| `holdings.sourceId` | term | Requests a holdings sourceId facet |
| `holdingsTypeId` | term | Requests a holdings typeId facet |
| `holdingsTags` | term | Requests a holdings tag facet |
| `holdings.tenantId` | term | Requests a holdings tenantId facet |

##### Item facets

Expand All @@ -680,12 +683,23 @@ GET /instances/facets?query=title all book&facet=source:5,discoverySuppress:2
| `headingType` | term | Requests a heading type facet |
| `subjectHeadings` | term | Requests a subject headings facet |
| `sourceFileId` | term | Requests a source files facet (default value: `NULL`) |
| `tenantId` | term | Requests a tenantId facet |
| `shared` | term | Requests a shared/local facet |

##### Contributors facets

| Option | Type | Description |
|:------------------------|:----:|:---------------------------------------|
| `contributorNameTypeId` | term | Requests a contributor name type facet |
| `instances.tenantId` | term | Requests a tenantId facet |
| `instances.shared` | term | Requests a shared/local facet |

##### Subjects facets

| Option | Type | Description |
|:------------------------|:----:|:---------------------------------------|
| `instances.tenantId` | term | Requests a tenantId facet |
| `instances.shared` | term | Requests a shared/local facet |

#### Sorting results

Expand Down
2 changes: 1 addition & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
},
{
"id": "search",
"version": "1.1",
"version": "1.2",
"handlers": [
{
"methods": [ "GET" ],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.folio.search.utils.SearchUtils.AUTHORITY_RESOURCE;
import static org.folio.search.utils.SearchUtils.CONTRIBUTOR_RESOURCE;
import static org.folio.search.utils.SearchUtils.INSTANCE_RESOURCE;
import static org.folio.search.utils.SearchUtils.INSTANCE_SUBJECT_RESOURCE;

import java.util.List;
import java.util.Map;
Expand All @@ -27,7 +28,8 @@ public class FacetsController implements FacetsApi {
private static final Map<RecordType, String> RECORD_TYPE_TO_RESOURCE_MAP = Map.of(
RecordType.INSTANCES, INSTANCE_RESOURCE,
RecordType.AUTHORITIES, AUTHORITY_RESOURCE,
RecordType.CONTRIBUTORS, CONTRIBUTOR_RESOURCE
RecordType.CONTRIBUTORS, CONTRIBUTOR_RESOURCE,
RecordType.SUBJECTS, INSTANCE_SUBJECT_RESOURCE
);

private final FacetService facetService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public SearchSourceBuilder convert(String query, String resource) {
*/
public SearchSourceBuilder convertForConsortia(String query, String resource) {
var sourceBuilder = convert(query, resource);
var queryBuilder = consortiumSearchHelper.filterQueryForActiveAffiliation(sourceBuilder.query());
var queryBuilder = consortiumSearchHelper.filterQueryForActiveAffiliation(sourceBuilder.query(), resource);

return sourceBuilder.query(queryBuilder);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.folio.search.model.index.AuthRefType.REFERENCE;
import static org.folio.search.model.types.ResponseGroupType.BROWSE;
import static org.folio.search.utils.LogUtils.collectionToLogMsg;
import static org.folio.search.utils.SearchUtils.AUTHORITY_RESOURCE;
import static org.opensearch.index.query.QueryBuilders.boolQuery;
import static org.opensearch.index.query.QueryBuilders.termQuery;
import static org.opensearch.index.query.QueryBuilders.termsQuery;
Expand Down Expand Up @@ -64,7 +65,7 @@ protected SearchSourceBuilder getSearchQuery(BrowseRequest request, BrowseContex

var boolQuery = boolQuery().filter(FILTER_QUERY);
ctx.getFilters().forEach(boolQuery::filter);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(boolQuery);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(boolQuery, AUTHORITY_RESOURCE);
return searchSource().query(query)
.searchAfter(new Object[] {ctx.getAnchor().toLowerCase(ROOT)})
.sort(fieldSort(request.getTargetField()).order(isBrowsingForward ? ASC : DESC))
Expand All @@ -80,7 +81,7 @@ protected SearchSourceBuilder getAnchorSearchQuery(BrowseRequest request, Browse

var boolQuery = boolQuery().filter(FILTER_QUERY).must(termQuery(request.getTargetField(), context.getAnchor()));
context.getFilters().forEach(boolQuery::filter);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(boolQuery);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(boolQuery, AUTHORITY_RESOURCE);
return searchSource().query(query).from(0).size(1).fetchSource(getIncludedSourceFields(request), null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.apache.commons.lang3.BooleanUtils.isFalse;
import static org.folio.search.model.types.ResponseGroupType.CN_BROWSE;
import static org.folio.search.utils.CallNumberUtils.getCallNumberAsLong;
import static org.folio.search.utils.SearchUtils.INSTANCE_RESOURCE;
import static org.opensearch.index.query.QueryBuilders.boolQuery;
import static org.opensearch.index.query.QueryBuilders.rangeQuery;
import static org.opensearch.script.Script.DEFAULT_SCRIPT_LANG;
Expand Down Expand Up @@ -59,7 +60,7 @@ public SearchSourceBuilder get(BrowseRequest request, BrowseContext ctx, boolean
var multiplier = queryConfiguration.getRangeQueryLimitMultiplier();
var pageSize = (int) Math.max(MIN_QUERY_SIZE, Math.ceil(ctx.getLimit(isBrowsingForward) * multiplier));
var initialQuery = getQuery(ctx, request, pageSize, isBrowsingForward);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(initialQuery);
var query = consortiumSearchHelper.filterQueryForActiveAffiliation(initialQuery, INSTANCE_RESOURCE);
var searchSource = searchSource().from(0).size(pageSize)
.query(query)
.sort(scriptSort(script, STRING).order(isBrowsingForward ? ASC : DESC));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected SearchSourceBuilder getAnchorSearchQuery(BrowseRequest request, Browse
log.debug("getAnchorSearchQuery:: by [request: {}]", request);
var boolQuery = boolQuery().must(termQuery(request.getTargetField(), context.getAnchor()));
context.getFilters().forEach(boolQuery::filter);
var query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(context, boolQuery);
var query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(context, boolQuery, request.getResource());
return searchSource().query(query)
.size(context.getLimit(context.isBrowsingForward()))
.from(0);
Expand All @@ -62,7 +62,7 @@ protected SearchSourceBuilder getSearchQuery(BrowseRequest req, BrowseContext ct
ctx.getFilters().forEach(boolQuery::filter);
query = boolQuery;
}
query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(ctx, query);
query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(ctx, query, req.getResource());
return searchSource().query(query)
.searchAfter(new Object[] {ctx.getAnchor().toLowerCase(ROOT), null, null, null})
.sort(fieldSort(req.getTargetField()).order(isBrowsingForward ? ASC : DESC))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void setConsortiumSearchHelper(ConsortiumSearchHelper consortiumSearchHel
protected SearchSourceBuilder getAnchorSearchQuery(BrowseRequest request, BrowseContext context) {
log.debug("getAnchorSearchQuery:: by [request: {}]", request);
var query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(context,
termQuery(request.getTargetField(), context.getAnchor()));
termQuery(request.getTargetField(), context.getAnchor()), request.getResource());
return searchSource().query(query)
.size(context.getLimit(context.isBrowsingForward()))
.from(0);
Expand All @@ -56,7 +56,7 @@ protected SearchSourceBuilder getSearchQuery(BrowseRequest req, BrowseContext ct
ctx.getFilters().forEach(boolQuery::filter);
query = boolQuery;
}
query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(ctx, query);
query = consortiumSearchHelper.filterBrowseQueryForActiveAffiliation(ctx, query, req.getResource());
return searchSource().query(query)
.searchAfter(new Object[] {ctx.getAnchor().toLowerCase(ROOT)})
.sort(fieldSort(req.getTargetField()).order(isBrowsingForward ? ASC : DESC))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.folio.search.domain.dto.ResourceEvent;
Expand All @@ -27,6 +28,7 @@
* Class designed to be executed only in scope of consortium central tenant id.
* So, it can be expected to always have central tenant id in {@link FolioExecutionContext}.
*/
@Log4j2
@Service
@RequiredArgsConstructor
public class ConsortiumInstanceService {
Expand All @@ -53,6 +55,7 @@ public class ConsortiumInstanceService {
* @return events that are not related to consortium tenants
*/
public List<ResourceEvent> saveInstances(List<ResourceEvent> instanceEvents) {
log.info("Saving consortium instances to DB [size: {}]", instanceEvents.size());
if (CollectionUtils.isEmpty(instanceEvents)) {
return instanceEvents;
}
Expand Down
Loading

0 comments on commit 2c8befd

Please sign in to comment.