use of com.rbmhtechnology.vind.api.query.facet.Interval in project vind by RBMHTechnology.
the class TestServerTest method testDateMathIntervals.
// MBDN-450
@Test
public void testDateMathIntervals() {
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime yesterday = ZonedDateTime.now(ZoneId.of("UTC")).minus(1, ChronoUnit.DAYS);
FieldDescriptor<String> title = new FieldDescriptorBuilder().setFullText(true).setFacet(true).buildTextField("title");
SingleValueFieldDescriptor.DateFieldDescriptor<ZonedDateTime> created = new FieldDescriptorBuilder().setFacet(true).setStored(true).buildDateField("created");
SingleValueFieldDescriptor.UtilDateFieldDescriptor<Date> modified = new FieldDescriptorBuilder().setFacet(true).buildUtilDateField("modified");
NumericFieldDescriptor<Long> category = new FieldDescriptorBuilder().setFacet(true).buildMultivaluedNumericField("category", Long.class);
DocumentFactory assets = new DocumentFactoryBuilder("asset").addField(title).addField(created).addField(category).addField(modified).build();
Document d1 = assets.createDoc("1").setValue(title, "Hello World").setValue(created, yesterday).setValue(modified, new Date()).setValues(category, Arrays.asList(1L, 2L));
Document d2 = assets.createDoc("2").setValue(title, "Hello Friends").setValue(created, now).setValue(modified, new Date()).addValue(category, 4L);
SearchServer server = testSearchServer.getSearchServer();
server.index(d1);
server.index(d2);
server.commit();
Interval.DateMathInterval i1 = Interval.dateInterval("past_24_hours", new DateMathExpression().sub(1, DAY), new DateMathExpression());
Interval.DateMathInterval i2 = Interval.dateInterval("past_week", new DateMathExpression().sub(7, DAY), new DateMathExpression());
FulltextSearch search = Search.fulltext("hello").filter(created.before(new DateMathExpression())).facet(query("anotherQuery", and(category.between(7, 10), created.after(new DateMathExpression().sub(1, DAY))))).facet(range("dates", created, new DateMathExpression().sub(1, DAY), new DateMathExpression(), Duration.ofHours(1))).facet(range("mod a", modified, new Date(), new Date(), 1L, TimeUnit.HOURS, "cats")).facet(interval("quality", category, Interval.numericInterval("low", 0L, 2L), Interval.numericInterval("high", 3L, 4L))).facet(interval("time", created, i1, i2)).facet(interval("time2", modified, Interval.dateInterval("early", new Date(0), new Date(10000)), Interval.dateInterval("late", new Date(10000), new Date(20000)))).facet(interval("time3", modified, Interval.dateInterval("early", new DateMathExpression(), new DateMathExpression().add(10000, MILLISECONDS)), Interval.dateInterval("late", new DateMathExpression().add(10000, MILLISECONDS), new DateMathExpression().add(20000, MILLISECONDS)))).page(1, 25).sort(desc(created));
PageResult result = (PageResult) server.execute(search, assets);
assertEquals(2, result.getNumOfResults());
assertEquals(2, result.getResults().size());
assertEquals("2", result.getResults().get(0).getId());
assertEquals("asset", result.getResults().get(0).getType());
assertEquals("2", result.getResults().get(0).getId());
assertEquals("asset", result.getResults().get(0).getType());
assertTrue(now.equals(result.getResults().get(0).getValue(created)));
assertTrue(now.equals(result.getResults().get(0).getValue("created")));
assertEquals(2, result.getFacetResults().getIntervalFacet("quality").getValues().size());
assertEquals(2, result.getFacetResults().getIntervalFacet("time").getValues().size());
System.out.println(result);
PageResult next = (PageResult) result.nextPage();
SearchResult prev = next.previousPage();
TermFacetResult<Long> facet = result.getFacetResults().getTermFacet(category);
RangeFacetResult<ZonedDateTime> dates = result.getFacetResults().getRangeFacet("dates", ZonedDateTime.class);
ZonedDateTime rangeDate = dates.getValues().get(0).getValue();
}
use of com.rbmhtechnology.vind.api.query.facet.Interval in project vind by RBMHTechnology.
the class TestServerTest method testEmbeddedSolr.
@Test
public void testEmbeddedSolr() {
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime yesterday = ZonedDateTime.now(ZoneId.of("UTC")).minus(1, ChronoUnit.DAYS);
FieldDescriptor<String> title = new FieldDescriptorBuilder().setFullText(true).setFacet(true).buildTextField("title");
SingleValueFieldDescriptor.DateFieldDescriptor<ZonedDateTime> created = new FieldDescriptorBuilder().setFacet(true).buildDateField("created");
SingleValueFieldDescriptor.UtilDateFieldDescriptor<Date> modified = new FieldDescriptorBuilder().setFacet(true).buildUtilDateField("modified");
NumericFieldDescriptor<Long> category = new FieldDescriptorBuilder().setFacet(true).buildMultivaluedNumericField("category", Long.class);
DocumentFactory assets = new DocumentFactoryBuilder("asset").addField(title).addField(created).addField(category).addField(modified).build();
Document d1 = assets.createDoc("1").setValue(title, "Hello World").setValue(created, yesterday).setValue(modified, new Date()).setValues(category, Arrays.asList(1L, 2L));
Document d2 = assets.createDoc("2").setValue(title, "Hello Friends").setValue(created, now).setValue(modified, new Date()).addValue(category, 4L);
SearchServer server = testSearchServer.getSearchServer();
server.index(d1);
server.index(d2);
server.commit();
Interval.ZonedDateTimeInterval i1 = Interval.dateInterval("past_24_hours", ZonedDateTime.now().minus(Duration.ofDays(1)), ZonedDateTime.now());
Interval.ZonedDateTimeInterval i2 = Interval.dateInterval("past_week", ZonedDateTime.now().minus(Duration.ofDays(7)), ZonedDateTime.now());
FulltextSearch search = Search.fulltext("hello").filter(category.between(0, 10)).filter(created.before(ZonedDateTime.now())).filter(modified.before(new Date())).facet(pivot("cats", category, created)).facet(pivot("catVStitle", category, title)).facet(stats("avg Cat", category, "cats", "catVStitle").count().sum().percentiles(9.9, 1.0).mean()).facet(stats("countDate", created).count().sum().mean()).facet(query("new An dHot", category.between(0, 5), "cats")).facet(query("anotherQuery", and(category.between(7, 10), created.after(ZonedDateTime.now().minus(Duration.ofDays(1)))))).facet(range("dates", created, ZonedDateTime.now().minus(Duration.ofDays(1)), ZonedDateTime.now(), Duration.ofHours(1))).facet(range("mod a", modified, new Date(), new Date(), 1L, TimeUnit.HOURS, "cats")).facet(interval("quality", category, Interval.numericInterval("low", 0L, 2L), Interval.numericInterval("high", 3L, 4L))).facet(interval("time", created, i1, i2)).facet(interval("time2", modified, Interval.dateInterval("early", new Date(0), new Date(10000)), Interval.dateInterval("late", new Date(10000), new Date(20000)))).facet(category).facet(created).facet(modified).page(1, 25).sort(desc(created));
PageResult result = (PageResult) server.execute(search, assets);
assertEquals(2, result.getNumOfResults());
assertEquals(2, result.getResults().size());
assertEquals("2", result.getResults().get(0).getId());
assertEquals("asset", result.getResults().get(0).getType());
assertEquals("2", result.getResults().get(0).getId());
assertEquals("asset", result.getResults().get(0).getType());
assertTrue(now.equals(result.getResults().get(0).getValue(created)));
assertTrue(now.equals(result.getResults().get(0).getValue("created")));
assertEquals(2, result.getFacetResults().getIntervalFacet("quality").getValues().size());
assertEquals(2, result.getFacetResults().getIntervalFacet("time").getValues().size());
System.out.println(result);
PageResult next = (PageResult) result.nextPage();
SearchResult prev = next.previousPage();
TermFacetResult<Long> facet = result.getFacetResults().getTermFacet(category);
RangeFacetResult<ZonedDateTime> dates = result.getFacetResults().getRangeFacet("dates", ZonedDateTime.class);
ZonedDateTime rangeDate = dates.getValues().get(0).getValue();
}
use of com.rbmhtechnology.vind.api.query.facet.Interval in project vind by RBMHTechnology.
the class SolrSearchServer method buildSolrQuery.
protected SolrQuery buildSolrQuery(FulltextSearch search, DocumentFactory factory) {
// build query
final SolrQuery query = new SolrQuery();
final String searchContext = search.getSearchContext();
if (search.getTimeZone() != null) {
query.set(CommonParams.TZ, search.getTimeZone());
}
// fulltext search
query.set(CommonParams.Q, search.getSearchString());
if (SearchConfiguration.get(SearchConfiguration.SEARCH_RESULT_SHOW_SCORE, true)) {
query.set(CommonParams.FL, "*,score");
} else {
query.set(CommonParams.FL, "*");
}
if (search.getGeoDistance() != null) {
final FieldDescriptor descriptor = factory.getField(search.getGeoDistance().getFieldName());
if (Objects.nonNull(descriptor)) {
query.setParam(CommonParams.FL, query.get(CommonParams.FL) + "," + DISTANCE + ":geodist()");
query.setParam("pt", search.getGeoDistance().getLocation().toString());
query.setParam("sfield", getFieldname(descriptor, UseCase.Facet, searchContext));
}
}
Collection<FieldDescriptor<?>> fulltext = factory.listFields().stream().filter(FieldDescriptor::isFullText).collect(Collectors.toList());
if (!fulltext.isEmpty()) {
query.setParam(DisMaxParams.QF, SolrUtils.Query.buildQueryFieldString(fulltext, searchContext));
query.setParam("defType", "edismax");
} else {
query.setParam(CommonParams.DF, TEXT);
}
// filters
query.add(CommonParams.FQ, "_type_:" + factory.getType());
if (search.hasFilter()) {
SolrUtils.Query.buildFilterString(search.getFilter(), factory, search.getChildrenFactory(), query, searchContext, search.getStrict());
}
// fulltext search deep search
if (search.isChildrenSearchEnabled()) {
// append childCount facet
search.facet(new Facet.SubdocumentFacet(factory));
// TODO: move to SolrUtils
final String parentSearchQuery = "((" + query.get(CommonParams.Q) + ") AND " + TYPE + ":" + factory.getType() + ")";
final String childrenSearchQuery = "_query_:\"{!parent which=" + TYPE + ":" + factory.getType() + "}(" + TYPE + ":" + search.getChildrenFactory().getType() + " AND (" + search.getChildrenSearchString().getEscapedSearchString() + "))\"";
query.set(CommonParams.Q, String.join(" ", parentSearchQuery, search.getChildrenSearchOperator().name(), childrenSearchQuery));
if (search.getChildrenSearchString().hasFilter()) {
// TODO clean up!
final String parentFilterQuery = "(" + String.join(" AND ", query.getFilterQueries()) + ")";
final String childrenFilterQuery = search.getChildrenSearchString().getFilter().accept(new SolrChildrenSerializerVisitor(factory, search.getChildrenFactory(), searchContext, search.getStrict()));
query.set(CommonParams.FQ, String.join(" ", parentFilterQuery, search.getChildrenSearchOperator().name(), "(" + childrenFilterQuery + ")"));
}
}
if (search.hasFacet()) {
query.setFacet(true);
query.setFacetMinCount(search.getFacetMinCount());
query.setFacetLimit(search.getFacetLimit());
// Query facets
search.getFacets().values().stream().filter(facet -> Facet.QueryFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.QueryFacet) genericFacet).forEach(queryFacet -> query.addFacetQuery(StringUtils.join(SolrUtils.Query.buildSolrFacetCustomName(SolrUtils.Query.buildFilterString(queryFacet.getFilter(), factory, search.getChildrenFactory(), searchContext, search.getStrict()), queryFacet))));
// Numeric Range facet
search.getFacets().values().stream().filter(facet -> Facet.NumericRangeFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.NumericRangeFacet) genericFacet).forEach(numericRangeFacet -> {
final UseCase useCase = UseCase.valueOf(numericRangeFacet.getScope().name());
final String fieldName = getFieldname(numericRangeFacet.getFieldDescriptor(), useCase, searchContext);
query.add(FacetParams.FACET_RANGE, SolrUtils.Query.buildSolrFacetCustomName(fieldName, numericRangeFacet));
query.add(String.format(Locale.ROOT, "f.%s.%s", fieldName, FacetParams.FACET_RANGE_START), numericRangeFacet.getStart().toString());
query.add(String.format(Locale.ROOT, "f.%s.%s", fieldName, FacetParams.FACET_RANGE_END), numericRangeFacet.getEnd().toString());
query.add(String.format(Locale.ROOT, "f.%s.%s", fieldName, FacetParams.FACET_RANGE_GAP), numericRangeFacet.getGap().toString());
/*query.addNumericRangeFacet(
SolrUtils.Query.buildSolrFacetCustomName(fieldName, numericRangeFacet.getName()),
numericRangeFacet.getStart(),
numericRangeFacet.getEnd(),
numericRangeFacet.getGap());*/
});
// Interval Range facet
search.getFacets().values().stream().filter(facet -> Facet.IntervalFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.IntervalFacet) genericFacet).forEach(intervalFacet -> {
final UseCase useCase = UseCase.valueOf(intervalFacet.getScope().name());
final String fieldName = getFieldname(intervalFacet.getFieldDescriptor(), useCase, searchContext);
query.add(FacetParams.FACET_INTERVAL, SolrUtils.Query.buildSolrFacetKey(intervalFacet.getName()) + fieldName);
for (Object o : intervalFacet.getIntervals()) {
// TODO why is this necessary?
Interval i = (Interval) o;
query.add(String.format("f.%s.%s", fieldName, FacetParams.FACET_INTERVAL_SET), String.format("%s%s%s,%s%s", SolrUtils.Query.buildSolrFacetKey(i.getName()), i.includesStart() ? "[" : "(", i.getStart() == null ? SOLR_WILDCARD : SolrUtils.Query.buildSolrQueryValue(i.getStart()), i.getEnd() == null ? SOLR_WILDCARD : SolrUtils.Query.buildSolrQueryValue(i.getEnd()), i.includesEnd() ? "]" : ")"));
}
});
// Date Range facet
search.getFacets().values().stream().filter(facet -> Facet.DateRangeFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.DateRangeFacet) genericFacet).forEach(dateRangeFacet -> generateDateRangeQuery(dateRangeFacet, query, searchContext));
// stats
search.getFacets().values().stream().filter(facet -> Facet.StatsFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.StatsFacet) genericFacet).forEach(statsFacet -> {
final UseCase useCase = UseCase.valueOf(statsFacet.getScope().name());
String fieldName = getFieldname(statsFacet.getField(), useCase, searchContext);
query.add(StatsParams.STATS, "true");
query.add(StatsParams.STATS_FIELD, SolrUtils.Query.buildSolrStatsQuery(fieldName, statsFacet));
});
// pivot facet
search.getFacets().values().stream().filter(facet -> Facet.PivotFacet.class.isAssignableFrom(facet.getClass())).map(genericFacet -> (Facet.PivotFacet) genericFacet).forEach(pivotFacet -> {
String[] fieldNames = pivotFacet.getFieldDescriptors().stream().map(fieldDescriptor -> getFieldname(fieldDescriptor, UseCase.Facet, searchContext)).toArray(String[]::new);
query.add(FacetParams.FACET_PIVOT, SolrUtils.Query.buildSolrPivotSubFacetName(pivotFacet.getName(), fieldNames));
});
// facet fields
final HashMap<String, Object> strings = SolrUtils.Query.buildJsonTermFacet(search.getFacets(), search.getFacetLimit(), factory, search.getChildrenFactory(), searchContext);
query.add("json.facet", strings.toString().replaceAll("=", ":"));
// facet Subdocument count
final String subdocumentFacetString = SolrUtils.Query.buildSubdocumentFacet(search, factory, searchContext);
if (Objects.nonNull(subdocumentFacetString)) {
query.add("json.facet", subdocumentFacetString);
}
}
// sorting
if (search.hasSorting()) {
final String sortString = SolrUtils.Query.buildSortString(search, search.getSorting(), factory);
query.set(CommonParams.SORT, sortString);
}
// TODO this is a mess
if (search.hasSorting()) {
query.set(DisMaxParams.BF, SolrUtils.Query.buildBoostFunction(search.getSorting(), searchContext));
}
// paging
switch(search.getResultSet().getType()) {
case page:
{
final Page resultSet = (Page) search.getResultSet();
query.setStart(resultSet.getOffset());
query.setRows(resultSet.getPagesize());
break;
}
case slice:
{
final Slice resultSet = (Slice) search.getResultSet();
query.setStart(resultSet.getOffset());
query.setRows(resultSet.getSliceSize());
break;
}
}
return query;
}
use of com.rbmhtechnology.vind.api.query.facet.Interval in project vind by RBMHTechnology.
the class TestServerTest method complexFieldTest.
// MBDN-455
@Test
public void complexFieldTest() {
SingleValuedComplexField.NumericComplexField<Taxonomy, Integer, String> numericComplexField = new ComplexFieldDescriptorBuilder<Taxonomy, Integer, String>().setFacet(true, tx -> Arrays.asList(tx.getId())).setFullText(true, tx -> Arrays.asList(tx.getTerm())).setSuggest(true, tx -> Arrays.asList(tx.getLabel())).buildNumericComplexField("numberFacetTaxonomy", Taxonomy.class, Integer.class, String.class);
SingleValuedComplexField.DateComplexField<Taxonomy, ZonedDateTime, String> dateComplexField = new ComplexFieldDescriptorBuilder<Taxonomy, ZonedDateTime, String>().setFacet(true, tx -> Arrays.asList(tx.getDate())).setFullText(true, tx -> Arrays.asList(tx.getTerm())).setSuggest(true, tx -> Arrays.asList(tx.getLabel())).buildDateComplexField("dateFacetTaxonomy", Taxonomy.class, ZonedDateTime.class, String.class);
SingleValuedComplexField.TextComplexField<Taxonomy, String, String> textComplexField = new ComplexFieldDescriptorBuilder<Taxonomy, String, String>().setFacet(true, tx -> Arrays.asList(tx.getLabel())).setSuggest(true, tx -> Arrays.asList(tx.getLabel())).setStored(true, tx -> tx.getTerm()).buildTextComplexField("textFacetTaxonomy", Taxonomy.class, String.class, String.class);
SingleValuedComplexField.DateComplexField<Taxonomy, ZonedDateTime, ZonedDateTime> dateStoredComplexField = new ComplexFieldDescriptorBuilder<Taxonomy, ZonedDateTime, ZonedDateTime>().setStored(true, tx -> tx.getDate()).buildSortableDateComplexField("dateStoredFacetTaxonomy", Taxonomy.class, ZonedDateTime.class, ZonedDateTime.class, cdf -> cdf.getDate());
MultiValuedComplexField.TextComplexField<Taxonomy, String, String> multiComplexField = new ComplexFieldDescriptorBuilder<Taxonomy, String, String>().setFacet(true, tx -> Arrays.asList(tx.getLabel())).setSuggest(true, tx -> Arrays.asList(tx.getLabel())).setStored(true, tx -> tx.getTerm()).buildMultivaluedTextComplexField("multiTextTaxonomy", Taxonomy.class, String.class, String.class);
FieldDescriptor<String> entityID = new FieldDescriptorBuilder().buildTextField("entityID");
SingleValueFieldDescriptor<Date> dateField = new FieldDescriptorBuilder().buildUtilDateField("date");
DocumentFactory assets = new DocumentFactoryBuilder("asset").addField(numericComplexField).addField(dateComplexField).addField(textComplexField).addField(dateField).addField(dateStoredComplexField).addField(entityID).addField(multiComplexField).build();
Document d1 = assets.createDoc("1").setValue(numericComplexField, new Taxonomy("uno", 1, "Uno label", ZonedDateTime.now())).setValue(dateComplexField, new Taxonomy("uno", 1, "Uno label", ZonedDateTime.now())).setValue(textComplexField, new Taxonomy("uno", 1, "Label", ZonedDateTime.now())).setValue(entityID, "123").setValue(dateStoredComplexField, new Taxonomy("uno", 1, "Label", ZonedDateTime.now())).setValues(multiComplexField, new Taxonomy("uno", 1, "Label", ZonedDateTime.now()), new Taxonomy("dos", 2, "Label dos", ZonedDateTime.now())).setValue(dateField, new Date());
Document d2 = assets.createDoc("2").setValue(numericComplexField, new Taxonomy("dos", 2, "dos label", ZonedDateTime.now())).setValue(dateComplexField, new Taxonomy("dos", 2, "dos label", ZonedDateTime.now())).setValue(textComplexField, new Taxonomy("uno", 2, "Label", ZonedDateTime.now())).setValue(entityID, "456").setValue(dateStoredComplexField, new Taxonomy("uno", 1, "Label", ZonedDateTime.now().plusMonths(1))).setValues(multiComplexField, new Taxonomy("uno", 1, "Label", ZonedDateTime.now()), new Taxonomy("dos", 1, "Label", ZonedDateTime.now())).setValue(dateField, new Date());
SearchServer server = testSearchServer.getSearchServer();
server.index(d1);
server.index(d2);
server.commit();
FulltextSearch searchAll = Search.fulltext().filter(and(textComplexField.isNotEmpty(Scope.Facet), or(Filter.eq(numericComplexField, 1), Filter.eq(numericComplexField, 2)), numericComplexField.between(0, 5), dateComplexField.between(ZonedDateTime.now().minusDays(3), ZonedDateTime.now().plusDays(3)), textComplexField.equals("Label"))).facet(interval("facetNumber", numericComplexField, Interval.numericInterval("[1-4]", 0, 5), Interval.numericInterval("[6-9]", 5, 10))).facet(interval("facetDateInterval", dateComplexField, Interval.dateInterval("3_days_ago_till_now-1_hour]", ZonedDateTime.now().minusDays(3), ZonedDateTime.now().minusHours(1)), Interval.dateInterval("[now-1_hour_till_the_future]", ZonedDateTime.now().minusHours(1), null))).facet(range("facetRange", numericComplexField, 0, 10, 5)).facet(range("facetDateRange", dateComplexField, ZonedDateTime.now().minusDays(3), ZonedDateTime.now().plusDays(3), Duration.ofDays(1))).facet(stats("facetStats", numericComplexField)).facet(stats("facetDateStats", dateComplexField)).facet(stats("facetTextStats", textComplexField)).facet(pivot("facetPivot", numericComplexField, entityID, dateComplexField, textComplexField)).facet(numericComplexField, entityID, dateComplexField, textComplexField).sort(desc(dateStoredComplexField));
final SearchResult searchResult = server.execute(searchAll, assets);
assertEquals("Stored text exists", "uno", searchResult.getResults().get(0).getValue(textComplexField));
assertThat("Multivalued text exists", (List<String>) searchResult.getResults().get(0).getValue(multiComplexField), containsInAnyOrder("uno", "dos"));
assertEquals("No of interval", 2, searchResult.getFacetResults().getIntervalFacet("facetNumber").getValues().size());
assertEquals("No of doc in interval", 2, searchResult.getFacetResults().getIntervalFacet("facetNumber").getValues().get(0).getCount());
assertEquals("No of StatsFacets", 3, searchResult.getFacetResults().getStatsFacets().size());
assertEquals("Stats Min: ", (Integer) 1, searchResult.getFacetResults().getStatsFacet("facetStats", Integer.class).getMin());
assertEquals("Stats Max: ", (Integer) 2, searchResult.getFacetResults().getStatsFacet("facetStats", Integer.class).getMax());
assertEquals("Stats Sum: ", (Integer) 3, searchResult.getFacetResults().getStatsFacet("facetStats", Integer.class).getSum());
final SuggestionResult suggestSearch = server.execute(Search.suggest("la").fields(numericComplexField, textComplexField), assets);
assertEquals(3, suggestSearch.size());
assertEquals("Label", suggestSearch.get(textComplexField).getValues().get(0).getValue());
assertEquals("Uno label", suggestSearch.get(numericComplexField).getValues().get(0).getValue());
}
Aggregations