SearchQuery: Replace dietThreshold() with diet()
This patch changes the query model to only allow a single chosen diet (and its corresponding threshold). This is being done mostly to simplify usage: the only code I have that makes use of the feature is unpublished and for reporting only - The web UI only uses one and I have no plans of allowing more than one.
- Id
- 190acc9a0f310a71b2bc0e8019c9ad17e3a300c8
- Author
- Caio
- Commit time
- 2019-05-24T15:21:29+02:00
Modified src/main/java/co/caio/cerberus/model/SearchQuery.java
package co.caio.cerberus.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import org.immutables.value.Value;
Optional<RangedSpec> carbohydrateContent();
- Map<String, Float> dietThreshold();
+ Optional<DietSpec> diet();
@Value.Derived
default long numSelectedFilters() {
return Stream.of(
- numIngredients(),
- prepTime(),
- cookTime(),
- totalTime(),
- calories(),
- fatContent(),
- proteinContent(),
- carbohydrateContent())
- .flatMap(Optional::stream)
- .count()
- + dietThreshold().size();
+ numIngredients(),
+ prepTime(),
+ cookTime(),
+ totalTime(),
+ calories(),
+ fatContent(),
+ proteinContent(),
+ carbohydrateContent(),
+ diet())
+ .flatMap(Optional::stream)
+ .count();
}
@Value.Derived
}
}
+ @Value.Immutable(builder = false)
+ @JsonFormat(shape = JsonFormat.Shape.ARRAY)
+ @JsonPropertyOrder({"name", "threshold"})
+ @JsonSerialize(as = ImmutableDietSpec.class)
+ @JsonDeserialize(as = ImmutableDietSpec.class)
+ interface DietSpec {
+ @Value.Parameter
+ String name();
+
+ @Value.Parameter
+ float threshold();
+
+ static DietSpec of(String name, float threshold) {
+ return ImmutableDietSpec.of(name, threshold);
+ }
+
+ @Value.Check
+ default void check() {
+ if (threshold() <= 0 || threshold() > 1) {
+ throw new IllegalStateException("Threshold must be > 0 and <= 1");
+ }
+ }
+ }
+
@Value.Check
default void check() {
if (maxResults() < 1) {
if (offset() < 0) {
throw new IllegalStateException("offset must be >= 0");
}
- dietThreshold()
- .forEach(
- (diet, score) -> {
- if (score <= 0 || score > 1) {
- throw new IllegalStateException("score must be in ]0,1]");
- }
- });
}
class Builder extends ImmutableSearchQuery.Builder {
- public Builder addMatchDiet(String dietName) {
- putDietThreshold(dietName, 1f);
+ public Builder diet(String dietName, float threshold) {
+ diet(DietSpec.of(dietName, threshold));
return this;
+ }
+
+ public Builder diet(String dietName) {
+ return diet(dietName, 1F);
}
}
}
Modified src/main/java/co/caio/cerberus/search/SearcherImpl.java
Occur.MUST));
searchQuery
- .dietThreshold()
- .forEach(
- (diet, score) ->
+ .diet()
+ .ifPresent(
+ (diet) ->
queryBuilder.add(
- FloatPoint.newRangeQuery(getFieldNameForDiet(diet), score, Float.MAX_VALUE),
+ FloatPoint.newRangeQuery(
+ getFieldNameForDiet(diet.name()), diet.threshold(), Float.MAX_VALUE),
Occur.MUST));
return queryBuilder.build();
Modified src/test/java/co/caio/cerberus/model/SearchQueryTest.java
@Test
void addMatchDietAlias() {
- assertEquals(
- new Builder().addMatchDiet("keto").build(),
- new Builder().putDietThreshold("keto", 1f).build());
+ assertEquals(new Builder().diet("keto").build(), new Builder().diet("keto", 1f).build());
}
@Test
void dietThresholds() {
- assertThrows(
- IllegalStateException.class, () -> new Builder().putDietThreshold("paleo", 0).build());
- assertThrows(
- IllegalStateException.class, () -> new Builder().putDietThreshold("lowcarb", -1).build());
- assertThrows(
- IllegalStateException.class, () -> new Builder().putDietThreshold("vegan", 1.1f).build());
- assertDoesNotThrow(() -> new Builder().putDietThreshold("paleo", 1.0f).build());
+ assertThrows(IllegalStateException.class, () -> new Builder().diet("paleo", 0).build());
+ assertThrows(IllegalStateException.class, () -> new Builder().diet("lowcarb", -1).build());
+ assertThrows(IllegalStateException.class, () -> new Builder().diet("vegan", 1.1f).build());
+ assertDoesNotThrow(() -> new Builder().diet("paleo", 1.0f).build());
}
@Test
assertEquals(0, builder.build().numSelectedFilters());
assertEquals(1, builder.numIngredients(RangedSpec.of(1, 10)).build().numSelectedFilters());
assertEquals(2, builder.carbohydrateContent(RangedSpec.of(0, 30)).build().numSelectedFilters());
- assertEquals(3, builder.addMatchDiet("keto").build().numSelectedFilters());
+ assertEquals(3, builder.diet("keto").build().numSelectedFilters());
}
}
Modified src/test/java/co/caio/cerberus/search/SearcherTest.java
searcher.search(
new SearchQuery.Builder()
.fulltext("vegetarian")
- .addMatchDiet("vegetarian")
+ .diet("vegetarian")
.maxResults(1)
.build());
assertEquals(nrVegetarianRecipes, result.totalHits());
// term<vegetarian> in the whole index would give us AT LEAST the same number
// as above, but maybe more since a recipe can be vegetarian without having to
// call itself vegetarian
- result =
- searcher.search(new SearchQuery.Builder().addMatchDiet("vegetarian").maxResults(1).build());
+ result = searcher.search(new SearchQuery.Builder().diet("vegetarian").maxResults(1).build());
assertTrue(result.totalHits() >= nrVegetarianRecipes);
}
.crawlUrl("https://who.cares")
.addIngredients("doesnt matter")
.addInstructions("nothing to do");
- indexer.addRecipe(recipeBuilder.putDiets("keto", 0.8f).putDiets("paleo", 0.5f).build());
- indexer.addRecipe(recipeBuilder.putDiets("keto", 0.6f).putDiets("paleo", 0.1f).build());
+ indexer.addRecipe(recipeBuilder.putDiets("keto", 0.8F).build());
+ indexer.addRecipe(recipeBuilder.putDiets("keto", 0.6F).build());
+ indexer.addRecipe(recipeBuilder.putDiets("keto", 1F).build());
indexer.commit();
var searcher = indexer.buildSearcher();
- var result = searcher.search(new SearchQuery.Builder().putDietThreshold("keto", 0.9f).build());
- assertEquals(0, result.totalHits());
+ var sqb = new SearchQuery.Builder();
- result =
- searcher.search(
- new SearchQuery.Builder()
- .putDietThreshold("keto", 0.8f)
- .putDietThreshold("paleo", 0.1f)
- .build());
- assertEquals(1, result.totalHits());
+ assertEquals(1, searcher.search(sqb.diet("keto").build()).totalHits());
+ assertEquals(1, searcher.search(sqb.diet("keto", 1F).build()).totalHits());
+ assertEquals(2, searcher.search(sqb.diet("keto", 0.7F).build()).totalHits());
+ assertEquals(3, searcher.search(sqb.diet("keto", 0.6F).build()).totalHits());
}
@Test