Skip to content

Commit

Permalink
#140 fallback lang suggest
Browse files Browse the repository at this point in the history
  • Loading branch information
marcos-lg committed Jun 14, 2024
1 parent dd2b2a7 commit 115e29a
Show file tree
Hide file tree
Showing 26 changed files with 562 additions and 312 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public class ParentDto {
long key;
String name;
int depth;
Long labelKey;
String label;
LanguageRegion labelLanguage;
String labelValue;
String fallbackLabel;
LanguageRegion fallbackLabelLanguage;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package org.gbif.vocabulary.persistence.dto;

import org.gbif.vocabulary.model.Label;
import lombok.Data;
import org.gbif.vocabulary.model.LanguageRegion;

import java.util.List;

import lombok.Data;

@Data
public class SuggestDto {

private long key;
private LanguageRegion langParam;
private LanguageRegion fallbackLangParam;
private String name;
private List<Label> labels;
private String label;
private LanguageRegion labelLang;
private List<ParentDto> parentDtos;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import com.google.common.base.Strings;

@MappedTypes({LanguageRegion.class})
public class LanguageRegionTypeHandler implements TypeHandler<LanguageRegion> {

Expand All @@ -36,16 +38,24 @@ public void setParameter(

@Override
public LanguageRegion getResult(ResultSet rs, String columnName) throws SQLException {
return LanguageRegion.fromLocale(rs.getString(columnName));
return convertResult(rs.getString(columnName));
}

@Override
public LanguageRegion getResult(ResultSet rs, int columnIndex) throws SQLException {
return LanguageRegion.fromLocale(rs.getString(columnIndex));
return convertResult(rs.getString(columnIndex));
}

@Override
public LanguageRegion getResult(CallableStatement cs, int columnIndex) throws SQLException {
return LanguageRegion.fromLocale(cs.getString(columnIndex));
return convertResult(cs.getString(columnIndex));
}

private LanguageRegion convertResult(String value) {
if (Strings.isNullOrEmpty(value)) {
return null;
}

return LanguageRegion.fromLocale(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.gbif.vocabulary.model.search.ChildrenResult;
import org.gbif.vocabulary.model.search.ConceptSearchParams;
import org.gbif.vocabulary.model.search.KeyNameResult;
import org.gbif.vocabulary.persistence.dto.SuggestDto;

import java.util.List;

Expand All @@ -31,8 +32,6 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import org.gbif.vocabulary.persistence.dto.SuggestDto;

/** Mapper for {@link Concept}. */
@Mapper
public interface ConceptMapper extends BaseMapper<Concept> {
Expand All @@ -59,7 +58,8 @@ List<SuggestDto> suggest(
@Param("query") String query,
@Param("vocabularyKey") long vocabularyKey,
@Nullable @Param("lang") LanguageRegion language,
@Nullable @Param("fallbackLang") LanguageRegion fallbackLang);
@Nullable @Param("fallbackLang") LanguageRegion fallbackLang,
@Param("limit") int limit);

/**
* Given a deprecated concept, it finds the current replacement, that's to say, the first
Expand Down Expand Up @@ -156,7 +156,8 @@ List<SuggestDto> suggestLatestRelease(
@Param("vocabularyKey") long vocabularyKey,
@Nullable @Param("lang") LanguageRegion languageFilter,
@Nullable @Param("fallbackLang") LanguageRegion fallbackLang,
@Param("vocabName") String vocabularyName);
@Param("vocabName") String vocabularyName,
@Param("limit") int limit);

List<String> findParentsLatestRelease(
@Param("key") long conceptKey, @Param("vocabName") String vocabularyName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.gbif.vocabulary.model.Vocabulary;
import org.gbif.vocabulary.model.search.KeyNameResult;
import org.gbif.vocabulary.model.search.VocabularySearchParams;
import org.gbif.vocabulary.persistence.dto.SuggestDto;

import java.util.List;

Expand All @@ -40,8 +41,11 @@ List<Vocabulary> list(

Long getKeyByName(@Param("name") String name);

List<KeyNameResult> suggest(
@Param("query") String query, @Nullable @Param("lang") LanguageRegion language);
List<SuggestDto> suggest(
@Param("query") String query,
@Nullable @Param("lang") LanguageRegion language,
@Nullable @Param("fallbackLang") LanguageRegion fallbackLang,
@Param("limit") int limit);

/**
* Searches for a similar vocabulary whose name or any of its labels are the same as the ones
Expand Down
17 changes: 10 additions & 7 deletions core/src/main/java/org/gbif/vocabulary/service/ConceptService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.gbif.vocabulary.model.Tag;
import org.gbif.vocabulary.model.search.ChildrenResult;
import org.gbif.vocabulary.model.search.ConceptSearchParams;
import org.gbif.vocabulary.model.search.KeyNameResult;
import org.gbif.vocabulary.model.search.SuggestResult;

import java.util.List;

Expand Down Expand Up @@ -61,13 +61,15 @@ public interface ConceptService extends BaseService<Concept> {
* @param vocabularyKey key of the vocabulary
* @param languageRegion locale to filter by
* @param fallbackLanguageRegion fallback locale to show in the response
* @param limit to limit the results, up to 20
* @return a list of up to 20 suggested concepts
*/
List<KeyNameResult> suggest(
List<SuggestResult> suggest(
String query,
long vocabularyKey,
@Nullable LanguageRegion languageRegion,
@Nullable LanguageRegion fallbackLanguageRegion);
@Nullable LanguageRegion fallbackLanguageRegion,
@Nullable Integer limit);

/**
* Deprecates a concept with a replacement.
Expand Down Expand Up @@ -187,15 +189,16 @@ PagingResponse<Concept> listLatestRelease(
@Nullable ConceptSearchParams params, @Nullable Pageable page, String vocabularyName);

/**
* It works as {@link #suggest(String, long, LanguageRegion, LanguageRegion)} but it queries the
* latest release of the vocabulary instead of the actual data.
* It works as {@link #suggest(String, long, LanguageRegion, LanguageRegion, Integer)} but it
* queries the latest release of the vocabulary instead of the actual data.
*/
List<KeyNameResult> suggestLatestRelease(
List<SuggestResult> suggestLatestRelease(
String query,
long vocabularyKey,
@Nullable LanguageRegion languageRegion,
@Nullable LanguageRegion fallbackLanguageRegion,
String vocabularyName);
String vocabularyName,
Integer limit);

/**
* It works as {@link #getByNameAndVocabulary(String, String)} but it queries the latest release
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.gbif.vocabulary.model.LanguageRegion;
import org.gbif.vocabulary.model.Vocabulary;
import org.gbif.vocabulary.model.search.KeyNameResult;
import org.gbif.vocabulary.model.search.SuggestResult;
import org.gbif.vocabulary.model.search.VocabularySearchParams;

import java.util.List;
Expand Down Expand Up @@ -52,9 +53,15 @@ public interface VocabularyService extends BaseService<Vocabulary> {
*
* @param query suggestion
* @param languageRegion locale to filter by
* @param fallbackLanguageRegion fallback locale to show in the response
* @param limit to limit the results, up to 20
* @return a list of up to 20 suggested vocabularies
*/
List<KeyNameResult> suggest(String query, @Nullable LanguageRegion languageRegion);
List<SuggestResult> suggest(
String query,
@Nullable LanguageRegion languageRegion,
@Nullable LanguageRegion fallbackLanguageRegion,
@Nullable Integer limit);

/**
* Deprecates a vocabulary with a replacement.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.gbif.vocabulary.model.search.ChildrenResult;
import org.gbif.vocabulary.model.search.ConceptSearchParams;
import org.gbif.vocabulary.model.search.KeyNameResult;
import org.gbif.vocabulary.model.search.SuggestResult;
import org.gbif.vocabulary.model.utils.PostPersist;
import org.gbif.vocabulary.model.utils.PrePersist;
import org.gbif.vocabulary.persistence.dto.ParentDto;
Expand All @@ -38,7 +39,6 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -68,6 +68,7 @@
@Validated
public class DefaultConceptService implements ConceptService {

private static final int DEFAULT_SUGGEST_LIMIT = 20;
private final ConceptMapper conceptMapper;
private final VocabularyMapper vocabularyMapper;

Expand Down Expand Up @@ -177,80 +178,44 @@ public PagingResponse<Concept> list(
}

@Override
public List<KeyNameResult> suggest(
public List<SuggestResult> suggest(
String query,
long vocabularyKey,
@Nullable LanguageRegion languageRegion,
@Nullable LanguageRegion fallbackLanguageRegion) {
@Nullable LanguageRegion fallbackLanguageRegion,
Integer limit) {
query = query != null ? query : "";
limit = limit != null ? limit : DEFAULT_SUGGEST_LIMIT;
List<SuggestDto> dtos =
conceptMapper.suggest(query, vocabularyKey, languageRegion, fallbackLanguageRegion);

return convertSuggestResults(languageRegion, fallbackLanguageRegion, dtos);
conceptMapper.suggest(query, vocabularyKey, languageRegion, fallbackLanguageRegion, limit);
return convertSuggestResults(dtos);
}

private static List<KeyNameResult> convertSuggestResults(
LanguageRegion languageRegion, LanguageRegion fallbackLanguageRegion, List<SuggestDto> dtos) {
private static List<SuggestResult> convertSuggestResults(List<SuggestDto> dtos) {
return dtos.stream()
.map(
dto -> {
KeyNameResult keyNameResult = new KeyNameResult();
keyNameResult.setKey(dto.getKey());
keyNameResult.setName(dto.getName());
keyNameResult.setLabels(dto.getLabels());

Function<List<Label>, List<Label>> filterLabels =
labels -> {
if (languageRegion != null && fallbackLanguageRegion != null) {
// keep only the ones of the language requested if they exist
List<Label> langLabels =
labels.stream()
.filter(l -> l.getLanguage().equals(languageRegion))
.collect(Collectors.toList());

if (!langLabels.isEmpty()) {
return langLabels;
}
}
return labels;
};

keyNameResult.setLabels(filterLabels.apply(dto.getLabels()));

keyNameResult.setParents(
SuggestResult suggestResult = new SuggestResult();
suggestResult.setName(dto.getName());
suggestResult.setLabel(dto.getLabel());
suggestResult.setLabelLanguage(dto.getLabelLang());
suggestResult.setParents(
dto.getParentDtos().stream()
.collect(
Collectors.toMap(
ParentDto::getKey,
p -> {
KeyNameResult.Parent parent = new KeyNameResult.Parent();
parent.setKey(p.getKey());
parent.setName(p.getName());
parent.setDepth(p.getDepth());
Label label =
Label.builder()
.key(p.getLabelKey())
.value(p.getLabelValue())
.language(p.getLabelLanguage())
.build();
parent.getLabels().add(label);
return parent;
},
(p1, p2) -> {
p1.getLabels().addAll(p2.getLabels());
return p1;
}))
.values()
.stream()
.sorted(Comparator.comparing(ParentDto::getDepth))
.map(
p -> {
p.setLabels(filterLabels.apply(p.getLabels()));
return p;
SuggestResult.Parent parent = new SuggestResult.Parent();
parent.setName(p.getName());
parent.setLabel(
p.getLabel() != null ? p.getLabel() : p.getFallbackLabel());
parent.setLabelLanguage(
p.getLabelLanguage() != null
? p.getLabelLanguage()
: p.getFallbackLabelLanguage());
return parent;
})
.sorted(Comparator.comparing(KeyNameResult.Parent::getDepth))
.collect(Collectors.toList()));

return keyNameResult;
return suggestResult;
})
.collect(Collectors.toList());
}
Expand Down Expand Up @@ -555,25 +520,28 @@ public PagingResponse<Concept> listLatestRelease(
}

@Override
public List<KeyNameResult> suggestLatestRelease(
public List<SuggestResult> suggestLatestRelease(
String query,
long vocabularyKey,
LanguageRegion languageRegion,
LanguageRegion fallbackLanguageRegion,
String vocabularyName) {
String vocabularyName,
Integer limit) {
checkArgument(!Strings.isNullOrEmpty(vocabularyName));
checkArgument(conceptMapper.existsReleaseView(vocabularyName.toLowerCase()));

query = query != null ? query : "";
limit = limit != null ? limit : DEFAULT_SUGGEST_LIMIT;
List<SuggestDto> dtos =
conceptMapper.suggestLatestRelease(
query,
vocabularyKey,
languageRegion,
fallbackLanguageRegion,
vocabularyName.toLowerCase());
vocabularyName.toLowerCase(),
limit);

return convertSuggestResults(languageRegion, fallbackLanguageRegion, dtos);
return convertSuggestResults(dtos);
}

@Override
Expand Down
Loading

0 comments on commit 115e29a

Please sign in to comment.