diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/ListingCodec.java b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/ListingCodec.java index 9870f5afb0b2121be9a451d77ba3d648c63c9fea..ef2c7070044c8152877d7af86c23fee119e060b3 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/ListingCodec.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/codecs/ListingCodec.java @@ -72,8 +72,6 @@ public class ListingCodec implements CollectibleCodec<Listing> { doc.put(DatabaseFieldNames.LISTING_BODY, value.getTeaser()); doc.put(DatabaseFieldNames.LISTING_TEASER, value.getBody()); doc.put(DatabaseFieldNames.MARKETPLACE_FAVORITES, value.getFavoriteCount()); - doc.put(DatabaseFieldNames.RECENT_INSTALLS, value.getInstallsRecent()); - doc.put(DatabaseFieldNames.TOTAL_INSTALLS, value.getInstallsTotal()); doc.put(DatabaseFieldNames.LICENSE_TYPE, value.getLicense()); doc.put(DatabaseFieldNames.LISTING_STATUS, value.getStatus()); doc.put(DatabaseFieldNames.UPDATE_DATE, DateTimeHelper.toRFC3339(value.getUpdateDate())); @@ -112,8 +110,8 @@ public class ListingCodec implements CollectibleCodec<Listing> { out.setTeaser(document.getString(DatabaseFieldNames.LISTING_TEASER)); out.setBody(document.getString(DatabaseFieldNames.LISTING_BODY)); out.setStatus(document.getString(DatabaseFieldNames.LISTING_STATUS)); - out.setInstallsRecent(document.getInteger(DatabaseFieldNames.RECENT_INSTALLS)); - out.setInstallsTotal(document.getInteger(DatabaseFieldNames.TOTAL_INSTALLS)); + out.setInstallsRecent(document.getInteger(DatabaseFieldNames.RECENT_INSTALLS,0)); + out.setInstallsTotal(document.getInteger(DatabaseFieldNames.TOTAL_INSTALLS,0)); out.setLicense(document.getString(DatabaseFieldNames.LICENSE_TYPE)); out.setFavoriteCount(document.getLong(DatabaseFieldNames.MARKETPLACE_FAVORITES)); out.setFoundationMember(document.getBoolean(DatabaseFieldNames.FOUNDATION_MEMBER_FLAG)); diff --git a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java index 1fc8d175309b924458a05deb3f8863697e6398a7..9aadaa4e0d7ff710be10a06ef3468bf0c22b7ac1 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java +++ b/src/main/java/org/eclipsefoundation/marketplace/dto/filter/ListingFilter.java @@ -25,6 +25,7 @@ import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Field; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; +import com.mongodb.client.model.UnwindOptions; /** * Filter implementation for the {@linkplain Listing} class. @@ -95,7 +96,7 @@ public class ListingFilter implements DtoFilter<Listing> { aggs.add(Aggregates.lookup(DtoTableNames.INSTALL_METRIC.getTableName(), DatabaseFieldNames.DOCID, DatabaseFieldNames.DOCID, "installs")); // unwinds the installs out of arrays - aggs.add(Aggregates.unwind("$installs")); + aggs.add(Aggregates.unwind("$installs", new UnwindOptions().preserveNullAndEmptyArrays(true))); // push the installs counts to the listing, and remove the installs merged in aggs.add(Aggregates.addFields(new Field<String>(DatabaseFieldNames.RECENT_INSTALLS, "$installs.offset_0.count"), new Field<String>(DatabaseFieldNames.TOTAL_INSTALLS, "$installs.count"))); diff --git a/src/main/java/org/eclipsefoundation/marketplace/helper/DateTimeHelper.java b/src/main/java/org/eclipsefoundation/marketplace/helper/DateTimeHelper.java index 16df77d4628f107444fd5ad9db6403a75107d253..77c743faee67d0f87268fef8cdd7629805ddc473 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/helper/DateTimeHelper.java +++ b/src/main/java/org/eclipsefoundation/marketplace/helper/DateTimeHelper.java @@ -12,6 +12,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Date; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,6 +37,7 @@ public class DateTimeHelper { * 3339 format. */ public static Date toRFC3339(String dateString) { + if (StringUtils.isBlank(dateString)) return null; try { return Date.from(ZonedDateTime.parse(dateString, formatter).toInstant()); } catch (DateTimeParseException e) { @@ -52,6 +54,7 @@ public class DateTimeHelper { * @return the RFC 3339 format date string. */ public static String toRFC3339(Date date) { + if (date == null) return null; return formatter.format(date.toInstant().atZone(ZoneId.of("UTC"))); } diff --git a/src/main/java/org/eclipsefoundation/marketplace/model/MongoQuery.java b/src/main/java/org/eclipsefoundation/marketplace/model/MongoQuery.java index a392fb61948b1b5151ec2c77b68c3b8a32631c04..547f3ba149d5bc60da6cddcd4925d913bb509449 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/model/MongoQuery.java +++ b/src/main/java/org/eclipsefoundation/marketplace/model/MongoQuery.java @@ -106,14 +106,25 @@ public class MongoQuery<T> { out.add(Aggregates.match(filter)); } // add base aggregates (joins) - out.addAll(aggregates); + out.addAll(aggregates); + if (sort != null) { + out.add(Aggregates.sort(sort)); + } + // check if the page param has been set, defaulting to the first page if not set + Optional<String> pageOpt = wrapper.getFirstParam(UrlParameterNames.PAGE); + int page = 1; + if (pageOpt.isPresent() && StringUtils.isNumeric(pageOpt.get())) { + int tmpPage = Integer.parseInt(pageOpt.get()); + if (tmpPage > 0) { + page = tmpPage; + LOGGER.debug("Found a set page of {} for current query",page); + } + } + out.add(Aggregates.skip((page - 1) * limit)); // add sample if we aren't sorting if ((sort == null || SortOrder.RANDOM.equals(order)) && dtoFilter.useLimit()) { out.add(Aggregates.sample(limit)); } - if (sort != null) { - out.add(Aggregates.sort(sort)); - } return out; } @@ -133,8 +144,6 @@ public class MongoQuery<T> { } private void setSort(String sortField, String sortOrder, List<Bson> filters) { - Optional<String> lastOpt = wrapper.getFirstParam(UrlParameterNames.LAST_SEEN); - List<Sortable<?>> fields = SortableHelper.getSortableFields(getDocType()); Optional<Sortable<?>> fieldContainer = SortableHelper.getSortableFieldByName(fields, sortField); if (fieldContainer.isPresent()) { @@ -142,17 +151,9 @@ public class MongoQuery<T> { // add sorting query if the sortOrder matches a defined order switch (order) { case ASCENDING: - // if last seen is set, add a filter to shift the results - if (lastOpt.isPresent()) { - filters.add(Filters.gte(sortField, fieldContainer.get().castValue(lastOpt.get()))); - } this.sort = Filters.eq(sortField, order.getOrder()); break; case DESCENDING: - // if last seen is set, add a filter to shift the results - if (lastOpt.isPresent()) { - filters.add(Filters.lte(sortField, fieldContainer.get().castValue(lastOpt.get()))); - } this.sort = Filters.eq(sortField, order.getOrder()); break; default: diff --git a/src/main/java/org/eclipsefoundation/marketplace/namespace/UrlParameterNames.java b/src/main/java/org/eclipsefoundation/marketplace/namespace/UrlParameterNames.java index a9352a63a1fb046f7a309752f9c1f58839b75a55..94045917d1f52f458542dee941d48ba7b40f8bc6 100644 --- a/src/main/java/org/eclipsefoundation/marketplace/namespace/UrlParameterNames.java +++ b/src/main/java/org/eclipsefoundation/marketplace/namespace/UrlParameterNames.java @@ -17,7 +17,7 @@ package org.eclipsefoundation.marketplace.namespace; public final class UrlParameterNames { public static final String QUERY_STRING = "q"; - public static final String LAST_SEEN = "last"; + public static final String PAGE = "page"; public static final String LIMIT = "limit"; public static final String SORT = "sort"; public static final String OS = "os";