public QueryResult<Notification> query(NotificationQuery query) { int limit = (query.getLimit() <= 500) ? query.getLimit() : 500; if (StringUtils.isNotBlank(query.getNotificationId())) { NotificationEntity notificationEntity = findNotificationById(query.getNotificationId()); return ListQueryResult.newSingle(Notification.class, notificationEntity.toNotification()); } else if (StringUtils.isNotBlank(query.getTrackingId())) { errorSuffix = "by tracking id " + query.getTrackingId(); String trackingId = query.getTrackingId(); viewQuery = CouchViewQuery.builder(CouchConst.NOTIFICATION_DESIGN_NAME, RequestCouchView.ByTrackingId.name()) .key(trackingId) .limit(limit + 1) .skip(query.getOffset()) .build(); } else if (StringUtils.isNotBlank(query.getTopic())) { errorSuffix = "by topic" + query.getTopic(); String topic = query.getTopic().toLowerCase(); viewQuery = CouchViewQuery.builder(CouchConst.NOTIFICATION_DESIGN_NAME, NotificationCouchView.ByTopicAndCreatedAt.name()) .start(topic, "\\ufff0") .end(topic, null) .limit(limit + 1) .skip(query.getOffset()) .descending(true) .build(); } else if (StringUtils.isNotBlank(query.getTraitKey()) && StringUtils.isNotBlank(query.getTraitValue())) { errorSuffix = String.format("by trait key: %s value: %s", query.getTraitKey(), query.getTraitValue()); String traitKey = query.getTraitKey().toLowerCase();