Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cn-browse): support aliases for callNumberTypeId filters #733

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Call Numbers Browse: Implement Call Number Browse Config ([MSEARCH-863](https://folio-org.atlassian.net/browse/MSEARCH-863))
* Call Numbers Browse: Implement Indexing and Re-indexing Mechanisms for Call-Numbers ([MSEARCH-864](https://folio-org.atlassian.net/browse/MSEARCH-864))
* Call Numbers Browse: Implement Browsing Endpoint for Call-Numbers ([MSEARCH-865](https://folio-org.atlassian.net/browse/MSEARCH-865))
* Call Numbers Browse: Support aliases for callNumberTypeId filters ([MSEARCH-942](https://folio-org.atlassian.net/browse/MSEARCH-942))

### Bug fixes
* Remove shelving order calculation for local call-number types
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,12 @@ does not produce any values, so the following search options will return an empt
|:------------------------|:----:|:------------------------------------|:------------------------------------------------|
| `contributorNameTypeId` | term | `contributorNameTypeId == "123456"` | Matches contributors with `123456` name type id |

##### Call-numbers search options

| Option | Type | Example | Description |
|:-------------------|:----:|:-------------------------------|:--------------------------------------------------------------------------------------------------------------------------------|
| `callNumberTypeId` | term | `callNumberTypeId == "123456"` | Matches call-numbers with `123456` call-number type id. Support aliases by call-number browse options: `callNumberTypeId == lc` |

#### Search Facets

Facets can be retrieved by using following API `GET /{recordType}/facets`. It consumes following request parameters:
Expand Down Expand Up @@ -876,6 +882,14 @@ GET /instances/facets?query=title all book&facet=source:5,discoverySuppress:2
| `instances.tenantId` | term | Requests a tenantId facet |
| `instances.shared` | term | Requests a shared/local facet |

##### Classifications facets

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

#### Sorting results

The default sorting is by relevancy. The `sortBy` clause is used to define sorting, for example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.folio.search.cql.builders.TermQueryBuilder;
import org.folio.search.cql.searchterm.SearchTermProcessor;
import org.folio.search.exception.RequestValidationException;
import org.folio.search.exception.ValidationException;
import org.folio.search.model.metadata.PlainFieldDescription;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static org.opensearch.index.query.QueryBuilders.multiMatchQuery;
import static org.opensearch.index.query.QueryBuilders.scriptQuery;
import static org.opensearch.index.query.QueryBuilders.termQuery;
import static org.opensearch.index.query.QueryBuilders.termsQuery;

import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -46,6 +47,9 @@ public QueryBuilder getFulltextQuery(Object term, String fieldName, ResourceType

@Override
public QueryBuilder getTermLevelQuery(Object term, String fieldName, ResourceType resource, String fieldIndex) {
if (term instanceof String[] termArray) {
return termArray.length > 1 ? termsQuery(fieldName, termArray) : termQuery(fieldName, termArray[0]);
}
return EMPTY_ARRAY.equals(term) && KEYWORD_FIELD_INDEX.equals(fieldIndex)
? getEmptyArrayScriptQuery(fieldName)
: termQuery(fieldName, term);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import static org.folio.search.utils.CallNumberUtils.normalizeCallNumberComponents;
import static org.folio.search.utils.SearchUtils.ASTERISKS_SIGN;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.folio.search.cql.searchterm;

import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.BrowseOptionType;
import org.folio.search.domain.dto.BrowseType;
import org.folio.search.service.consortium.BrowseConfigServiceDecorator;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class CallNumberTypeIdSearchTermProcessor implements SearchTermProcessor {

private final BrowseConfigServiceDecorator configService;

@Override
public Object getSearchTerm(String inputTerm) {
try {
var browseOptionType = BrowseOptionType.fromValue(inputTerm);
var browseConfig = configService.getConfig(BrowseType.CALL_NUMBER, browseOptionType);
return browseConfig.getTypeIds().stream().map(Object::toString).toArray(String[]::new);
} catch (IllegalArgumentException e) {
return inputTerm;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we need to log some message here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's expected flow. If the input is not parsed to the enum then we proceed with input without any changes.
So, I believe no log msg needed

}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.isBlank;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import static org.folio.search.utils.CallNumberUtils.getShelfKeyFromCallNumber;
import static org.folio.search.utils.CallNumberUtils.normalizeEffectiveShelvingOrder;
Expand All @@ -8,6 +8,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import org.folio.search.cql.SuDocCallNumber;
import org.folio.search.domain.dto.CallNumberType;
import org.marc4j.callnum.CallNumber;
import org.marc4j.callnum.DeweyCallNumber;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import lombok.RequiredArgsConstructor;
import org.folio.search.service.setter.instance.IsbnProcessor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import lombok.RequiredArgsConstructor;
import org.folio.search.service.lccn.LccnNormalizer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

import lombok.RequiredArgsConstructor;
import org.folio.search.service.setter.instance.OclcProcessor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.folio.search.cql;
package org.folio.search.cql.searchterm;

public interface SearchTermProcessor {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.opensearch.index.query.QueryBuilder;
import org.opensearch.index.query.RangeQueryBuilder;
import org.opensearch.index.query.TermQueryBuilder;
import org.opensearch.index.query.TermsQueryBuilder;
import org.opensearch.search.aggregations.AggregationBuilders;
import org.opensearch.search.aggregations.bucket.terms.IncludeExclude;
import org.opensearch.search.builder.SearchSourceBuilder;
Expand Down Expand Up @@ -75,7 +76,8 @@ public static boolean isDisjunctionFilterQuery(QueryBuilder query, Predicate<Str
* @return true if query is type of filter, false - otherwise
*/
public static boolean isFilterQuery(QueryBuilder query, Predicate<String> check) {
return query instanceof TermQueryBuilder && check.test(((TermQueryBuilder) query).fieldName())
return query instanceof TermsQueryBuilder && check.test(((TermsQueryBuilder) query).fieldName())
|| query instanceof TermQueryBuilder && check.test(((TermQueryBuilder) query).fieldName())
|| query instanceof RangeQueryBuilder && check.test(((RangeQueryBuilder) query).fieldName());
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/model/instance_call_number.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
},
"callNumberTypeId": {
"index": "keyword",
"searchTypes": [ "facet" ],
"showInResponse": [ "browse" ]
"searchTypes": [ "filter", "facet" ],
"showInResponse": [ "browse" ],
"searchTermProcessor": "callNumberTypeIdSearchTermProcessor"
},
"volume": {
"index": "source",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
value:
items:
- fullCallNumber: "Bilingualism: a bibliography of 1000 references with special reference to Wales."
shelfKey: "Bilingualism: a bibliography of 1000 references with special reference to Wales."
- fullCallNumber: "NS 1 .B5"
callNumber: "NS 1 .B4"
callNumberTypeId: "2b94c631-fca9-4892-a730-03ee529ff6c3"
prefix: "pref1"
isAnchor: true
totalRecords: 1
instance:
id: "d20569a7-9bba-44dd-9ad5-6f8f1d24ee1f"
title: "Bilingualism: a bibliography of 1000 references with special reference to Wales."
contributors:
- name: "Eichhorst, Georg."
publication:
- publisher: "Duncker und Humblot"
dateOfPublication: "1976"
electronicAccess:
- uri: "http://www.example.com"
notes:
- note: "Staff note"
items:
- barcode: "12345"
notes:
- note: "Staff note"
electronicAccess:
- uri: "http://www.example.com"
holdings:
- callNumber: "FS 124.44"
notes:
- note: "Staff note"
electronicAccess:
- uri: "http://www.example.com"
prev: "string"
next: "string"
totalRecords: 1
- fullCallNumber: "NS 1 .B5 suf-1801"
callNumber: "NS 1 .B5"
suffix: "suf-1801"
isAnchor: true
totalRecords: 1
prev: "NS 1 .B4"
next: "NS 1 .B5 suf-1801"
totalRecords: 2
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: query
in: query
required: true
description: |
A CQL query string with filter conditions must include anchor query with range conditions. Anchor field is `number`.
A CQL query string with filter conditions must include anchor query with range conditions. Anchor field is `fullCallNumber`.
Filters support logic operators `AND` and `OR`. All filters should be combined in parentheses.
Anchor will be included only if `<=` or `>=` are used in the query. Otherwise, the empty row will be added if `highlightMatch` is equal to `true`.
<table>
Expand Down Expand Up @@ -30,6 +30,18 @@ description: |
<td>==</td>
<td>Filter by shared/non-shared in consortium</td>
</tr>
<tr>
<td>instances.locationId</td>
<td>string</td>
<td>==</td>
<td>Filter by location ID</td>
</tr>
<tr>
<td>callNumberTypeId</td>
<td>string</td>
<td>==</td>
<td>Filter by call-number type ID</td>
</tr>
</tbody>
</table>
schema:
Expand All @@ -45,5 +57,5 @@ examples:
value: number >= "DT571.F84"
summary: Search for all classification numbers before "DT571.F84"
browseAroundWithFilters:
value: (number >= "DT571.F84" or number < "DT571.F84") and instances.shared==false
value: (number >= "DT571.F84" or number < "DT571.F84") and instances.shared==false and instances.locationId=="2b94c631-fca9-4892-a730-03ee529ff6c3"
summary: Search for local classification numbers before and after "DT571.F84"
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ get:
application/json:
examples:
browseResult:
$ref: '../../examples/result/browseClassificationNumberResult.yaml'
$ref: '../../examples/result/browseCallNumberResult.yaml'
schema:
$ref: '../../schemas/response/callNumberBrowseResult.yaml'
'400':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ private static Stream<Arguments> facetQueriesProvider() {
arguments("cql.allRecords=1", array("instances.locationId"), mapOf("instances.locationId",
facet(facetItem(locations.get(1), 42), facetItem(locations.get(2), 34), facetItem(locations.get(3), 24)))),
arguments("callNumberTypeId=\"" + LC.getId() + "\"", array("instances.locationId"), mapOf("instances.locationId",
facet(facetItem(locations.get(1), 8), facetItem(locations.get(2), 8), facetItem(locations.get(3), 4)))),
arguments("callNumberTypeId==lc", array("instances.locationId"), mapOf("instances.locationId",
facet(facetItem(locations.get(1), 8), facetItem(locations.get(2), 8), facetItem(locations.get(3), 4))))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import org.folio.search.cql.searchterm.CallNumberSearchTermProcessor;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.stream.Stream;
import org.folio.search.cql.searchterm.ClassificationNumberSearchTermProcessor;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.Optional;
import java.util.stream.Stream;
import org.folio.search.cql.CqlSearchQueryConverterTest.ConverterTestConfiguration;
import org.folio.search.cql.searchterm.SearchTermProcessor;
import org.folio.search.exception.RequestValidationException;
import org.folio.search.exception.SearchServiceException;
import org.folio.search.model.metadata.PlainFieldDescription;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Optional;
import java.util.Set;
import org.folio.search.cql.builders.TermQueryBuilder;
import org.folio.search.cql.searchterm.SearchTermProcessor;
import org.folio.search.exception.RequestValidationException;
import org.folio.search.exception.ValidationException;
import org.folio.search.service.metadata.LocalSearchFieldProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.List;
import java.util.stream.Collectors;
import org.folio.search.cql.searchterm.EffectiveShelvingOrderTermProcessor;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.mockito.Mockito.when;

import java.util.List;
import org.folio.search.cql.searchterm.IsbnSearchTermProcessor;
import org.folio.search.service.setter.instance.IsbnProcessor;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.mockito.Mockito.when;

import java.util.Optional;
import org.folio.search.cql.searchterm.LccnSearchTermProcessor;
import org.folio.search.service.lccn.LccnNormalizer;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import org.folio.search.cql.searchterm.OclcSearchTermProcessor;
import org.folio.search.service.setter.instance.OclcProcessor;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.opensearch.index.query.QueryBuilders.multiMatchQuery;
import static org.opensearch.index.query.QueryBuilders.scriptQuery;
import static org.opensearch.index.query.QueryBuilders.termQuery;
import static org.opensearch.index.query.QueryBuilders.termsQuery;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -95,6 +96,19 @@ void getTermLevelQuery_positive_emptyArrayValueNonKeywordField() {
assertThat(actual).isEqualTo(termQuery("field", "[]"));
}

@Test
void getTermLevelQuery_positive_arrayOfTermsWithSizeLessThen1() {
var actual = queryBuilder.getTermLevelQuery(new String[]{"val1"}, "field", UNKNOWN, null);
assertThat(actual).isEqualTo(termQuery("field", "val1"));
}


@Test
void getTermLevelQuery_positive_arrayOfTermsWithSizeGreaterThen1() {
var actual = queryBuilder.getTermLevelQuery(new String[]{"val1", "val2"}, "field", UNKNOWN, null);
assertThat(actual).isEqualTo(termsQuery("field", "val1", "val2"));
}

@Test
void getSupportedComparators_positive() {
var actual = queryBuilder.getSupportedComparators();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import org.apache.lucene.search.TotalHits;
import org.folio.search.configuration.properties.SearchConfigurationProperties;
import org.folio.search.cql.CqlSearchQueryConverter;
import org.folio.search.cql.EffectiveShelvingOrderTermProcessor;
import org.folio.search.cql.searchterm.EffectiveShelvingOrderTermProcessor;
import org.folio.search.domain.dto.Instance;
import org.folio.search.domain.dto.Item;
import org.folio.search.domain.dto.ItemEffectiveCallNumberComponents;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ private static Stream<Arguments> isFilterQueryDataProvider() {
arguments(rangeQuery("f").gt(10), false),
arguments(matchQuery(FIELD, "value"), false),
arguments(termQuery(FIELD, "value"), true),
arguments(termQuery("f", "v"), false)
);
arguments(termQuery("f", "v"), false),
arguments(termsQuery(FIELD, "value"), true)
);
}
}
Loading