001package io.ebean;
002
003import io.ebean.search.Match;
004import io.ebean.search.MultiMatch;
005import io.ebean.search.TextCommonTerms;
006import io.ebean.search.TextQueryString;
007import io.ebean.search.TextSimple;
008
009import javax.annotation.Nonnull;
010import javax.annotation.Nullable;
011import javax.persistence.NonUniqueResultException;
012import java.sql.Connection;
013import java.sql.Timestamp;
014import java.util.Collection;
015import java.util.List;
016import java.util.Map;
017import java.util.Optional;
018import java.util.Set;
019import java.util.function.Consumer;
020import java.util.function.Predicate;
021
022/**
023 * List of Expressions that make up a where or having clause.
024 * <p>
025 * An ExpressionList is returned from {@link Query#where()}.
026 * </p>
027 * <p>
028 * The ExpressionList has a list of convenience methods that create the standard
029 * expressions and add them to this list.
030 * </p>
031 * <p>
032 * The ExpressionList also duplicates methods that are found on the Query such
033 * as findList() and order(). The purpose of these methods is provide a fluid
034 * API. The upside of this approach is that you can build and execute a query
035 * via chained methods. The down side is that this ExpressionList object has
036 * more methods than you would initially expect (the ones duplicated from
037 * Query).
038 * </p>
039 *
040 * @see Query#where()
041 */
042public interface ExpressionList<T> {
043
044  /**
045   * Return the query that owns this expression list.
046   * <p>
047   * This is a convenience method solely to support a fluid API where the
048   * methods are chained together. Adding expressions returns this expression
049   * list and this method can be used after that to return back the original
050   * query so that further things can be added to it.
051   * </p>
052   */
053  Query<T> query();
054
055  /**
056   * Controls, if paginated queries should always append an 'order by id' statement at the end to
057   * guarantee a deterministic sort result. This may affect performance.
058   * If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
059   * this query provides a deterministic result.
060   */
061  Query<T> orderById(boolean orderById);
062
063  /**
064   * Set the order by clause replacing the existing order by clause if there is
065   * one.
066   * <p>
067   * This follows SQL syntax using commas between each property with the
068   * optional asc and desc keywords representing ascending and descending order
069   * respectively.
070   */
071  ExpressionList<T> order(String orderByClause);
072
073  /**
074   * Set the order by clause replacing the existing order by clause if there is
075   * one.
076   * <p>
077   * This follows SQL syntax using commas between each property with the
078   * optional asc and desc keywords representing ascending and descending order
079   * respectively.
080   */
081  ExpressionList<T> orderBy(String orderBy);
082
083  /**
084   * Return the OrderBy so that you can append an ascending or descending
085   * property to the order by clause.
086   * <p>
087   * This will never return a null. If no order by clause exists then an 'empty'
088   * OrderBy object is returned.
089   * <p>
090   * This is the same as <code>orderBy()</code>
091   */
092  OrderBy<T> order();
093
094  /**
095   * Return the OrderBy so that you can append an ascending or descending
096   * property to the order by clause.
097   * <p>
098   * This will never return a null. If no order by clause exists then an 'empty'
099   * OrderBy object is returned.
100   * <p>
101   * This is the same as <code>order()</code>
102   */
103  OrderBy<T> orderBy();
104
105  /**
106   * Deprecated migrate to {@link #orderBy(String)}
107   */
108  @Deprecated
109  Query<T> setOrderBy(String orderBy);
110
111  /**
112   * Apply the path properties to the query replacing the select and fetch clauses.
113   */
114  Query<T> apply(FetchPath fetchPath);
115
116  /**
117   * Perform an 'As of' query using history tables to return the object graph
118   * as of a time in the past.
119   * <p>
120   * To perform this query the DB must have underlying history tables.
121   * </p>
122   *
123   * @param asOf the date time in the past at which you want to view the data
124   */
125  Query<T> asOf(Timestamp asOf);
126
127  /**
128   * Execute the query against the draft set of tables.
129   */
130  Query<T> asDraft();
131
132  /**
133   * Convert the query to a DTO bean query.
134   * <p>
135   * We effectively use the underlying ORM query to build the SQL and then execute
136   * and map it into DTO beans.
137   */
138  <D> DtoQuery<D> asDto(Class<D> dtoClass);
139
140  /**
141   * Return the underlying query as an UpdateQuery.
142   * <p>
143   * Typically this is used with query beans to covert a query bean
144   * query into an UpdateQuery like the examples below.
145   * </p>
146   *
147   * <pre>{@code
148   *
149   *  int rowsUpdated = new QCustomer()
150   *       .name.startsWith("Rob")
151   *       .asUpdate()
152   *       .set("active", false)
153   *       .update();;
154   *
155   * }</pre>
156   *
157   * <pre>{@code
158   *
159   *   int rowsUpdated = new QContact()
160   *       .notes.note.startsWith("Make Inactive")
161   *       .email.endsWith("@foo.com")
162   *       .customer.id.equalTo(42)
163   *       .asUpdate()
164   *       .set("inactive", true)
165   *       .setRaw("email = lower(email)")
166   *       .update();
167   *
168   * }</pre>
169   */
170  UpdateQuery<T> asUpdate();
171
172  /**
173   * Execute the query with the given lock type and WAIT.
174   * <p>
175   * Note that <code>forUpdate()</code> is the same as
176   * <code>withLock(LockType.UPDATE)</code>.
177   * <p>
178   * Provides us with the ability to explicitly use Postgres
179   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
180   */
181  Query<T> withLock(Query.LockType lockType);
182
183  /**
184   * Execute the query with the given lock type and lock wait.
185   * <p>
186   * Note that <code>forUpdateNoWait()</code> is the same as
187   * <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
188   * <p>
189   * Provides us with the ability to explicitly use Postgres
190   * SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
191   */
192  Query<T> withLock(Query.LockType lockType, Query.LockWait lockWait);
193
194  /**
195   * Execute using "for update" clause which results in the DB locking the record.
196   */
197  Query<T> forUpdate();
198
199  /**
200   * Execute using "for update" clause with No Wait option.
201   * <p>
202   * This is typically a Postgres and Oracle only option at this stage.
203   * </p>
204   */
205  Query<T> forUpdateNoWait();
206
207  /**
208   * Execute using "for update" clause with Skip Locked option.
209   * <p>
210   * This is typically a Postgres and Oracle only option at this stage.
211   * </p>
212   */
213  Query<T> forUpdateSkipLocked();
214
215  /**
216   * Execute the query including soft deleted rows.
217   */
218  Query<T> setIncludeSoftDeletes();
219
220  /**
221   * Execute the query using the given transaction.
222   */
223  Query<T> usingTransaction(Transaction transaction);
224
225  /**
226   * Execute the query using the given connection.
227   */
228  Query<T> usingConnection(Connection connection);
229
230  /**
231   * Execute as a delete query deleting the 'root level' beans that match the predicates
232   * in the query.
233   * <p>
234   * Note that if the query includes joins then the generated delete statement may not be
235   * optimal depending on the database platform.
236   * </p>
237   *
238   * @return the number of rows that were deleted.
239   */
240  int delete();
241
242  /**
243   * Execute as a delete query deleting the 'root level' beans that match the predicates
244   * in the query.
245   * <p>
246   * Note that if the query includes joins then the generated delete statement may not be
247   * optimal depending on the database platform.
248   * </p>
249   *
250   * @return the number of rows that were deleted.
251   */
252  int delete(Transaction transaction);
253
254  /**
255   * Execute as a update query.
256   *
257   * @return the number of rows that were updated.
258   * @see UpdateQuery
259   */
260  int update();
261
262  /**
263   * Execute as a update query with the given transaction.
264   *
265   * @return the number of rows that were updated.
266   * @see UpdateQuery
267   */
268  int update(Transaction transaction);
269
270  /**
271   * Execute the query returning true if a row is found.
272   * <p>
273   * The query is executed using max rows of 1 and will only select the id property.
274   * This method is really just a convenient way to optimise a query to perform a
275   * 'does a row exist in the db' check.
276   * </p>
277   *
278   * <h2>Example:</h2>
279   * <pre>{@code
280   *
281   *   boolean userExists = query().where().eq("email", "[email protected]").exists();
282   *
283   * }</pre>
284   *
285   * <h2>Example using a query bean:</h2>
286   * <pre>{@code
287   *
288   *   boolean userExists = new QContact().email.equalTo("[email protected]").exists();
289   *
290   * }</pre>
291   *
292   * @return True if the query finds a matching row in the database
293   */
294  boolean exists();
295
296  /**
297   * Execute the query iterating over the results.
298   *
299   * @see Query#findIterate()
300   */
301  QueryIterator<T> findIterate();
302
303  /**
304   * Execute the query process the beans one at a time.
305   *
306   * @see Query#findEach(Consumer)
307   */
308  void findEach(Consumer<T> consumer);
309
310  /**
311   * Execute the query processing the beans one at a time with the ability to
312   * stop processing before reading all the beans.
313   *
314   * @see Query#findEachWhile(Predicate)
315   */
316  void findEachWhile(Predicate<T> consumer);
317
318  /**
319   * Execute the query returning a list.
320   *
321   * @see Query#findList()
322   */
323  @Nonnull
324  List<T> findList();
325
326  /**
327   * Execute the query returning the list of Id's.
328   *
329   * @see Query#findIds()
330   */
331  @Nonnull
332  <A> List<A> findIds();
333
334  /**
335   * Return the count of entities this query should return.
336   * <p>
337   * This is the number of 'top level' or 'root level' entities.
338   * </p>
339   */
340  int findCount();
341
342  /**
343   * Execute the query returning a set.
344   *
345   * @see Query#findSet()
346   */
347  @Nonnull
348  Set<T> findSet();
349
350  /**
351   * Execute the query returning a map.
352   *
353   * @see Query#findMap()
354   */
355  @Nonnull
356  <K> Map<K, T> findMap();
357
358  /**
359   * Execute the query returning a list of values for a single property.
360   *
361   * <h3>Example 1:</h3>
362   * <pre>{@code
363   *
364   *  List<String> names =
365   *    DB.find(Customer.class)
366   *      .select("name")
367   *      .order().asc("name")
368   *      .findSingleAttributeList();
369   *
370   * }</pre>
371   *
372   * <h3>Example 2:</h3>
373   * <pre>{@code
374   *
375   *  List<String> names =
376   *    DB.find(Customer.class)
377   *      .setDistinct(true)
378   *      .select("name")
379   *      .where().eq("status", Customer.Status.NEW)
380   *      .order().asc("name")
381   *      .setMaxRows(100)
382   *      .findSingleAttributeList();
383   *
384   * }</pre>
385   *
386   * @return the list of values for the selected property
387   */
388  @Nonnull
389  <A> List<A> findSingleAttributeList();
390
391  /**
392   * Execute a query returning a single value of a single property/column.
393   * <pre>{@code
394   *
395   *  String name =
396   *    DB.find(Customer.class)
397   *      .select("name")
398   *      .where().eq("id", 42)
399   *      .findSingleAttribute();
400   *
401   * }</pre>
402   */
403  default <A> A findSingleAttribute() {
404    List<A> list = findSingleAttributeList();
405    return !list.isEmpty() ? list.get(0) : null;
406  }
407
408  /**
409   * Execute the query returning a single bean or null (if no matching
410   * bean is found).
411   * <p>
412   * If more than 1 row is found for this query then a NonUniqueResultException is
413   * thrown.
414   * </p>
415   *
416   * @throws NonUniqueResultException if more than one result was found
417   * @see Query#findOne()
418   */
419  @Nullable
420  T findOne();
421
422  /**
423   * Execute the query returning an optional bean.
424   */
425  @Nonnull
426  Optional<T> findOneOrEmpty();
427
428  /**
429   * Execute find row count query in a background thread.
430   * <p>
431   * This returns a Future object which can be used to cancel, check the
432   * execution status (isDone etc) and get the value (with or without a
433   * timeout).
434   * </p>
435   *
436   * @return a Future object for the row count query
437   */
438  @Nonnull
439  FutureRowCount<T> findFutureCount();
440
441  /**
442   * Execute find Id's query in a background thread.
443   * <p>
444   * This returns a Future object which can be used to cancel, check the
445   * execution status (isDone etc) and get the value (with or without a
446   * timeout).
447   * </p>
448   *
449   * @return a Future object for the list of Id's
450   */
451  @Nonnull
452  FutureIds<T> findFutureIds();
453
454  /**
455   * Execute find list query in a background thread.
456   * <p>
457   * This returns a Future object which can be used to cancel, check the
458   * execution status (isDone etc) and get the value (with or without a
459   * timeout).
460   * </p>
461   *
462   * @return a Future object for the list result of the query
463   */
464  @Nonnull
465  FutureList<T> findFutureList();
466
467  /**
468   * Return a PagedList for this query using firstRow and maxRows.
469   * <p>
470   * The benefit of using this over findList() is that it provides functionality to get the
471   * total row count etc.
472   * </p>
473   * <p>
474   * If maxRows is not set on the query prior to calling findPagedList() then a
475   * PersistenceException is thrown.
476   * </p>
477   * <pre>{@code
478   *
479   *  PagedList<Order> pagedList = DB.find(Order.class)
480   *       .setFirstRow(50)
481   *       .setMaxRows(20)
482   *       .findPagedList();
483   *
484   *       // fetch the total row count in the background
485   *       pagedList.loadRowCount();
486   *
487   *       List<Order> orders = pagedList.getList();
488   *       int totalRowCount = pagedList.getTotalRowCount();
489   *
490   * }</pre>
491   *
492   * @return The PagedList
493   * @see Query#findPagedList()
494   */
495  @Nonnull
496  PagedList<T> findPagedList();
497
498  /**
499   * Return versions of a @History entity bean.
500   * <p>
501   * Generally this query is expected to be a find by id or unique predicates query.
502   * It will execute the query against the history returning the versions of the bean.
503   * </p>
504   */
505  @Nonnull
506  List<Version<T>> findVersions();
507
508  /**
509   * Return versions of a @History entity bean between the 2 timestamps.
510   * <p>
511   * Generally this query is expected to be a find by id or unique predicates query.
512   * It will execute the query against the history returning the versions of the bean.
513   * </p>
514   */
515  @Nonnull
516  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
517
518  /**
519   * Add some filter predicate expressions to the many property.
520   */
521  @Nonnull
522  ExpressionList<T> filterMany(String manyProperty);
523
524  /**
525   * Add filter expressions to the many property.
526   *
527   * <pre>{@code
528   *
529   *   DB.find(Customer.class)
530   *   .where()
531   *   .eq("name", "Rob")
532   *   .filterMany("orders", "status = ?", Status.NEW)
533   *   .findList();
534   *
535   * }</pre>
536   *
537   * @param manyProperty The many property
538   * @param expressions  Filter expressions with and, or and ? or ?1 type bind parameters
539   * @param params       Bind parameters used in the expressions
540   */
541  ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
542
543  /**
544   * Specify specific properties to fetch on the main/root bean (aka partial
545   * object).
546   *
547   * @see Query#select(String)
548   */
549  Query<T> select(String properties);
550
551  /**
552   * Apply the fetchGroup which defines what part of the object graph to load.
553   */
554  Query<T> select(FetchGroup<T> fetchGroup);
555
556  /**
557   * Set whether this query uses DISTINCT.
558   * <p>
559   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
560   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
561   * </p>
562   * <pre>{@code
563   *
564   *   List<Customer> customers =
565   *       DB.find(Customer.class)
566   *          .setDistinct(true)
567   *          .select("name")     // only select the customer name
568   *          .findList();
569   *
570   * }</pre>
571   */
572  Query<T> setDistinct(boolean distinct);
573
574  /**
575   * Set the index(es) to search for a document store which uses partitions.
576   * <p>
577   * For example, when executing a query against ElasticSearch with daily indexes we can
578   * explicitly specify the indexes to search against.
579   * </p>
580   *
581   * @param indexName The index or indexes to search against
582   * @return This query
583   * @see Query#setDocIndexName(String)
584   */
585  Query<T> setDocIndexName(String indexName);
586
587  /**
588   * Set the first row to fetch.
589   *
590   * @see Query#setFirstRow(int)
591   */
592  ExpressionList<T> setFirstRow(int firstRow);
593
594  /**
595   * Set the maximum number of rows to fetch.
596   *
597   * @see Query#setMaxRows(int)
598   */
599  ExpressionList<T> setMaxRows(int maxRows);
600
601  /**
602   * Set the name of the property which values become the key of a map.
603   *
604   * @see Query#setMapKey(String)
605   */
606  Query<T> setMapKey(String mapKey);
607
608  /**
609   * Set to true when this query should use the bean cache.
610   * <p>
611   * This is now the same as setUseBeanCache(CacheMode.ON) and will be deprecated.
612   * </p>
613   *
614   * @see Query#setUseCache(boolean)
615   */
616  Query<T> setUseCache(boolean useCache);
617
618  /**
619   * Set the mode to use the bean cache when executing this query.
620   *
621   * @see Query#setBeanCacheMode(CacheMode)
622   */
623  Query<T> setBeanCacheMode(CacheMode beanCacheMode);
624
625  /**
626   * Set the {@link CacheMode} to use the query cache for executing this query.
627   *
628   * @see Query#setUseQueryCache(boolean)
629   */
630  Query<T> setUseQueryCache(CacheMode useCache);
631
632  /**
633   * Extended version for setDistinct in conjunction with "findSingleAttributeList";
634   * <pre>{@code
635   *
636   *  List<CountedValue<Order.Status>> orderStatusCount =
637   *
638   *     DB.find(Order.class)
639   *      .select("status")
640   *      .where()
641   *      .gt("orderDate", LocalDate.now().minusMonths(3))
642   *
643   *      // fetch as single attribute with a COUNT
644   *      .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
645   *      .findSingleAttributeList();
646   *
647   *     for (CountedValue<Order.Status> entry : orderStatusCount) {
648   *       System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
649   *     }
650   *
651   *   // produces
652   *
653   *   count:3 orderStatus:NEW
654   *   count:1 orderStatus:SHIPPED
655   *   count:1 orderStatus:COMPLETE
656   *
657   * }</pre>
658   */
659  Query<T> setCountDistinct(CountDistinctOrder orderBy);
660
661  /**
662   * Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>.
663   *
664   * @see Query#setUseQueryCache(CacheMode)
665   */
666  default Query<T> setUseQueryCache(boolean enabled) {
667    return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
668  }
669
670  /**
671   * Set to true if this query should execute against the doc store.
672   * <p>
673   * When setting this you may also consider disabling lazy loading.
674   * </p>
675   */
676  Query<T> setUseDocStore(boolean useDocsStore);
677
678  /**
679   * Set true if you want to disable lazy loading.
680   * <p>
681   * That is, once the object graph is returned further lazy loading is disabled.
682   * </p>
683   */
684  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
685
686  /**
687   * Disable read auditing for this query.
688   * <p>
689   * This is intended to be used when the query is not a user initiated query and instead
690   * part of the internal processing in an application to load a cache or document store etc.
691   * In these cases we don't want the query to be part of read auditing.
692   * </p>
693   */
694  Query<T> setDisableReadAuditing();
695
696  /**
697   * Set a label on the query (to help identify query execution statistics).
698   */
699  Query<T> setLabel(String label);
700
701  /**
702   * Add expressions to the having clause.
703   * <p>
704   * The having clause is only used for queries based on raw sql (via SqlSelect
705   * annotation etc).
706   * </p>
707   */
708  ExpressionList<T> having();
709
710  /**
711   * Add another expression to the where clause.
712   */
713  ExpressionList<T> where();
714
715  /**
716   * Add the expressions to this expression list.
717   *
718   * @param expressions The expressions that are parsed and added to this expression list
719   * @param params      Bind parameters to match ? or ?1 bind positions.
720   */
721  ExpressionList<T> where(String expressions, Object... params);
722
723  /**
724   * Path exists - for the given path in a JSON document.
725   * <pre>{@code
726   *
727   *   where().jsonExists("content", "path.other")
728   *
729   * }</pre>
730   *
731   * @param propertyName the property that holds a JSON document
732   * @param path         the nested path in the JSON document in dot notation
733   */
734  ExpressionList<T> jsonExists(String propertyName, String path);
735
736  /**
737   * Path does not exist - for the given path in a JSON document.
738   * <pre>{@code
739   *
740   *   where().jsonNotExists("content", "path.other")
741   *
742   * }</pre>
743   *
744   * @param propertyName the property that holds a JSON document
745   * @param path         the nested path in the JSON document in dot notation
746   */
747  ExpressionList<T> jsonNotExists(String propertyName, String path);
748
749  /**
750   * Equal to expression for the value at the given path in the JSON document.
751   * <pre>{@code
752   *
753   *   where().jsonEqualTo("content", "path.other", 34)
754   *
755   * }</pre>
756   *
757   * @param propertyName the property that holds a JSON document
758   * @param path         the nested path in the JSON document in dot notation
759   * @param value        the value used to test against the document path's value
760   */
761  ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value);
762
763  /**
764   * Not Equal to - for the given path in a JSON document.
765   * <pre>{@code
766   *
767   *   where().jsonNotEqualTo("content", "path.other", 34)
768   *
769   * }</pre>
770   *
771   * @param propertyName the property that holds a JSON document
772   * @param path         the nested path in the JSON document in dot notation
773   * @param value        the value used to test against the document path's value
774   */
775  ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value);
776
777  /**
778   * Greater than - for the given path in a JSON document.
779   * <pre>{@code
780   *
781   *   where().jsonGreaterThan("content", "path.other", 34)
782   *
783   * }</pre>
784   */
785  ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object value);
786
787  /**
788   * Greater than or equal to - for the given path in a JSON document.
789   * <pre>{@code
790   *
791   *   where().jsonGreaterOrEqual("content", "path.other", 34)
792   *
793   * }</pre>
794   */
795  ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object value);
796
797  /**
798   * Less than - for the given path in a JSON document.
799   * <pre>{@code
800   *
801   *   where().jsonLessThan("content", "path.other", 34)
802   *
803   * }</pre>
804   */
805  ExpressionList<T> jsonLessThan(String propertyName, String path, Object value);
806
807  /**
808   * Less than or equal to - for the given path in a JSON document.
809   * <pre>{@code
810   *
811   *   where().jsonLessOrEqualTo("content", "path.other", 34)
812   *
813   * }</pre>
814   */
815  ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object value);
816
817  /**
818   * Between - for the given path in a JSON document.
819   * <pre>{@code
820   *
821   *   where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime)
822   *
823   * }</pre>
824   */
825  ExpressionList<T> jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
826
827  /**
828   * Add an Expression to the list.
829   */
830  ExpressionList<T> add(Expression expr);
831
832  /**
833   * Add a list of Expressions to this ExpressionList.s
834   */
835  ExpressionList<T> addAll(ExpressionList<T> exprList);
836
837  /**
838   * Equal To - property is equal to a given value.
839   */
840  ExpressionList<T> eq(String propertyName, Object value);
841
842  /**
843   * Equal To or Null - property is equal to a given value or null.
844   */
845  ExpressionList<T> eqOrNull(String propertyName, Object value);
846
847  /**
848   * Not Equal To - property not equal to the given value.
849   */
850  ExpressionList<T> ne(String propertyName, Object value);
851
852  /**
853   * Case Insensitive Equal To - property equal to the given value (typically
854   * using a lower() function to make it case insensitive).
855   */
856  ExpressionList<T> ieq(String propertyName, String value);
857
858  /**
859   * Case Insensitive Not Equal To - property not equal to the given value (typically
860   * using a lower() function to make it case insensitive).
861   */
862  ExpressionList<T> ine(String propertyName, String value);
863
864  /**
865   * Value in Range between 2 properties.
866   *
867   * <pre>{@code
868   *
869   *    .startDate.inRangeWith(endDate, now)
870   *
871   *    // which equates to
872   *    startDate <= now and (endDate > now or endDate is null)
873   *
874   * }</pre>
875   *
876   * <p>
877   * This is a convenience expression combining a number of simple expressions.
878   * The most common use of this could be called "effective dating" where 2 date or
879   * timestamp columns represent the date range in which
880   */
881  ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
882
883  /**
884   * In Range - {@code property >= value1 and property < value2}.
885   * <p>
886   * Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
887   * </p>
888   */
889  ExpressionList<T> inRange(String propertyName, Object value1, Object value2);
890
891  /**
892   * Between - property between the two given values.
893   */
894  ExpressionList<T> between(String propertyName, Object value1, Object value2);
895
896  /**
897   * Between - value between the two properties.
898   */
899  ExpressionList<T> betweenProperties(String lowProperty, String highProperty, Object value);
900
901  /**
902   * Greater Than - property greater than the given value.
903   */
904  ExpressionList<T> gt(String propertyName, Object value);
905
906  /**
907   * Greater Than or Null - property greater than the given value or null.
908   */
909  ExpressionList<T> gtOrNull(String propertyName, Object value);
910
911  /**
912   * Greater Than or Equal to OR Null - <code> >= or null </code>.
913   */
914  ExpressionList<T> geOrNull(String propertyName, Object value);
915
916  /**
917   * Greater Than or Equal to - property greater than or equal to the given
918   * value.
919   */
920  ExpressionList<T> ge(String propertyName, Object value);
921
922  /**
923   * Less Than - property less than the given value.
924   */
925  ExpressionList<T> lt(String propertyName, Object value);
926
927  /**
928   * Less Than or Null - property less than the given value or null.
929   */
930  ExpressionList<T> ltOrNull(String propertyName, Object value);
931
932  /**
933   * Less Than or Equal to OR Null - <code> <= or null </code>.
934   */
935  ExpressionList<T> leOrNull(String propertyName, Object value);
936
937  /**
938   * Less Than or Equal to - property less than or equal to the given value.
939   */
940  ExpressionList<T> le(String propertyName, Object value);
941
942  /**
943   * Is Null - property is null.
944   */
945  ExpressionList<T> isNull(String propertyName);
946
947  /**
948   * Is Not Null - property is not null.
949   */
950  ExpressionList<T> isNotNull(String propertyName);
951
952  /**
953   * A "Query By Example" type of expression.
954   * <p>
955   * Pass in an example entity and for each non-null scalar properties an
956   * expression is added.
957   * </p>
958   * <p>
959   * By Default this case sensitive, will ignore numeric zero values and will
960   * use a Like for string values (you must put in your own wildcards).
961   * </p>
962   * <p>
963   * To get control over the options you can create an ExampleExpression and set
964   * those options such as case insensitive etc.
965   * </p>
966   * <pre>{@code
967   *
968   * // create an example bean and set the properties
969   * // with the query parameters you want
970   * Customer example = new Customer();
971   * example.setName("Rob%");
972   * example.setNotes("%something%");
973   *
974   * List<Customer> list =
975   *   DB.find(Customer.class)
976   *     .where().exampleLike(example)
977   *     .findList();
978   *
979   * }</pre>
980   * <p>
981   * Similarly you can create an ExampleExpression
982   * </p>
983   * <pre>{@code
984   *
985   * Customer example = new Customer();
986   * example.setName("Rob%");
987   * example.setNotes("%something%");
988   *
989   * // create a ExampleExpression with more control
990   * ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros();
991   *
992   * List<Customer> list = DB.find(Customer.class).where().add(qbe).findList();
993   *
994   * }</pre>
995   */
996  ExpressionList<T> exampleLike(Object example);
997
998  /**
999   * Case insensitive version of {@link #exampleLike(Object)}
1000   */
1001  ExpressionList<T> iexampleLike(Object example);
1002
1003  /**
1004   * Like - property like value where the value contains the SQL wild card
1005   * characters % (percentage) and _ (underscore).
1006   */
1007  ExpressionList<T> like(String propertyName, String value);
1008
1009  /**
1010   * Case insensitive Like - property like value where the value contains the
1011   * SQL wild card characters % (percentage) and _ (underscore). Typically uses
1012   * a lower() function to make the expression case insensitive.
1013   */
1014  ExpressionList<T> ilike(String propertyName, String value);
1015
1016  /**
1017   * Starts With - property like value%.
1018   */
1019  ExpressionList<T> startsWith(String propertyName, String value);
1020
1021  /**
1022   * Case insensitive Starts With - property like value%. Typically uses a
1023   * lower() function to make the expression case insensitive.
1024   */
1025  ExpressionList<T> istartsWith(String propertyName, String value);
1026
1027  /**
1028   * Ends With - property like %value.
1029   */
1030  ExpressionList<T> endsWith(String propertyName, String value);
1031
1032  /**
1033   * Case insensitive Ends With - property like %value. Typically uses a lower()
1034   * function to make the expression case insensitive.
1035   */
1036  ExpressionList<T> iendsWith(String propertyName, String value);
1037
1038  /**
1039   * Contains - property like %value%.
1040   */
1041  ExpressionList<T> contains(String propertyName, String value);
1042
1043  /**
1044   * Case insensitive Contains - property like %value%. Typically uses a lower()
1045   * function to make the expression case insensitive.
1046   */
1047  ExpressionList<T> icontains(String propertyName, String value);
1048
1049  /**
1050   * In expression using pairs of value objects.
1051   */
1052  ExpressionList<T> inPairs(Pairs pairs);
1053
1054  /**
1055   * In - using a subQuery.
1056   */
1057  ExpressionList<T> in(String propertyName, Query<?> subQuery);
1058
1059  /**
1060   * In - property has a value in the array of values.
1061   */
1062  ExpressionList<T> in(String propertyName, Object... values);
1063
1064  /**
1065   * In - property has a value in the collection of values.
1066   */
1067  ExpressionList<T> in(String propertyName, Collection<?> values);
1068
1069  /**
1070   * In where null or empty values means that no predicate is added to the query.
1071   * <p>
1072   * That is, only add the IN predicate if the values are not null or empty.
1073   * <p>
1074   * Without this we typically need to code an <code>if</code> block to only add
1075   * the IN predicate if the collection is not empty like:
1076   * </p>
1077   *
1078   * <h3>Without inOrEmpty()</h3>
1079   * <pre>{@code
1080   *
1081   *   query.where() // add some predicates
1082   *     .eq("status", Status.NEW);
1083   *
1084   *   if (ids != null && !ids.isEmpty()) {
1085   *     query.where().in("customer.id", ids);
1086   *   }
1087   *
1088   *   query.findList();
1089   *
1090   * }</pre>
1091   *
1092   * <h3>Using inOrEmpty()</h3>
1093   * <pre>{@code
1094   *
1095   *   query.where()
1096   *     .eq("status", Status.NEW)
1097   *     .inOrEmpty("customer.id", ids)
1098   *     .findList();
1099   *
1100   * }</pre>
1101   */
1102  ExpressionList<T> inOrEmpty(String propertyName, Collection<?> values);
1103
1104  /**
1105   * In - using a subQuery.
1106   * <p>
1107   * This is exactly the same as in() and provided due to "in" being a Kotlin keyword
1108   * (and hence to avoid the slightly ugly escaping when using in() in Kotlin)
1109   */
1110  default ExpressionList<T> isIn(String propertyName, Query<?> subQuery) {
1111    return in(propertyName, subQuery);
1112  }
1113
1114  /**
1115   * In - property has a value in the array of values.
1116   * <p>
1117   * This is exactly the same as in() and provided due to "in" being a Kotlin keyword
1118   * (and hence to avoid the slightly ugly escaping when using in() in Kotlin)
1119   */
1120  default ExpressionList<T> isIn(String propertyName, Object... values) {
1121    return in(propertyName, values);
1122  }
1123
1124  /**
1125   * In - property has a value in the collection of values.
1126   * <p>
1127   * This is exactly the same as in() and provided due to "in" being a Kotlin keyword
1128   * (and hence to avoid the slightly ugly escaping when using in() in Kotlin)
1129   */
1130  default ExpressionList<T> isIn(String propertyName, Collection<?> values) {
1131    return in(propertyName, values);
1132  }
1133
1134  /**
1135   * Not In - property has a value in the array of values.
1136   */
1137  ExpressionList<T> notIn(String propertyName, Object... values);
1138
1139  /**
1140   * Not In - property has a value in the collection of values.
1141   */
1142  ExpressionList<T> notIn(String propertyName, Collection<?> values);
1143
1144  /**
1145   * Not In - using a subQuery.
1146   */
1147  ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
1148
1149  /**
1150   * Is empty expression for collection properties.
1151   */
1152  ExpressionList<T> isEmpty(String propertyName);
1153
1154  /**
1155   * Is not empty expression for collection properties.
1156   */
1157  ExpressionList<T> isNotEmpty(String propertyName);
1158
1159  /**
1160   * Exists expression
1161   */
1162  ExpressionList<T> exists(Query<?> subQuery);
1163
1164  /**
1165   * Not exists expression
1166   */
1167  ExpressionList<T> notExists(Query<?> subQuery);
1168
1169  /**
1170   * Id IN a list of id values.
1171   */
1172  ExpressionList<T> idIn(Object... idValues);
1173
1174  /**
1175   * Id IN a collection of id values.
1176   */
1177  ExpressionList<T> idIn(Collection<?> idValues);
1178
1179  /**
1180   * Id Equal to - ID property is equal to the value.
1181   */
1182  ExpressionList<T> idEq(Object value);
1183
1184  /**
1185   * All Equal - Map containing property names and their values.
1186   * <p>
1187   * Expression where all the property names in the map are equal to the
1188   * corresponding value.
1189   * </p>
1190   *
1191   * @param propertyMap a map keyed by property names.
1192   */
1193  ExpressionList<T> allEq(Map<String, Object> propertyMap);
1194
1195  /**
1196   * Array property contains entries with the given values.
1197   */
1198  ExpressionList<T> arrayContains(String propertyName, Object... values);
1199
1200  /**
1201   * Array does not contain the given values.
1202   * <p>
1203   * Array support is effectively limited to Postgres at this time.
1204   * </p>
1205   */
1206  ExpressionList<T> arrayNotContains(String propertyName, Object... values);
1207
1208  /**
1209   * Array is empty - for the given array property.
1210   * <p>
1211   * Array support is effectively limited to Postgres at this time.
1212   * </p>
1213   */
1214  ExpressionList<T> arrayIsEmpty(String propertyName);
1215
1216  /**
1217   * Array is not empty - for the given array property.
1218   * <p>
1219   * Array support is effectively limited to Postgres at this time.
1220   * </p>
1221   */
1222  ExpressionList<T> arrayIsNotEmpty(String propertyName);
1223
1224  /**
1225   * Add expression for ANY of the given bit flags to be set.
1226   * <pre>{@code
1227   *
1228   * where().bitwiseAny("flags", BwFlags.HAS_BULK + BwFlags.HAS_COLOUR)
1229   *
1230   * }</pre>
1231   *
1232   * @param propertyName The property that holds the flags value
1233   * @param flags        The flags we are looking for
1234   */
1235  ExpressionList<T> bitwiseAny(String propertyName, long flags);
1236
1237  /**
1238   * Add expression for ALL of the given bit flags to be set.
1239   * <pre>{@code
1240   *
1241   * where().bitwiseAll("flags", BwFlags.HAS_BULK + BwFlags.HAS_COLOUR)
1242   *
1243   * }</pre>
1244   *
1245   * @param propertyName The property that holds the flags value
1246   * @param flags        The flags we are looking for
1247   */
1248  ExpressionList<T> bitwiseAll(String propertyName, long flags);
1249
1250  /**
1251   * Add expression for the given bit flags to be NOT set.
1252   * <pre>{@code
1253   *
1254   * where().bitwiseNot("flags", BwFlags.HAS_COLOUR)
1255   *
1256   * }</pre>
1257   *
1258   * @param propertyName The property that holds the flags value
1259   * @param flags        The flags we are looking for
1260   */
1261  ExpressionList<T> bitwiseNot(String propertyName, long flags);
1262
1263  /**
1264   * Add bitwise AND expression of the given bit flags to compare with the match/mask.
1265   * <p>
1266   * <pre>{@code
1267   *
1268   * // Flags Bulk + Size = Size
1269   * // ... meaning Bulk is not set and Size is set
1270   *
1271   * long selectedFlags = BwFlags.HAS_BULK + BwFlags.HAS_SIZE;
1272   * long mask = BwFlags.HAS_SIZE; // Only Size flag set
1273   *
1274   * where().bitwiseAnd("flags", selectedFlags, mask)
1275   *
1276   * }</pre>
1277   *
1278   * @param propertyName The property that holds the flags value
1279   * @param flags        The flags we are looking for
1280   */
1281  ExpressionList<T> bitwiseAnd(String propertyName, long flags, long match);
1282
1283  /**
1284   * Add raw expression with a single parameter.
1285   * <p>
1286   * The raw expression should contain a single ? or ?1
1287   * at the location of the parameter.  We use ?1 when binding a
1288   * collection for an IN expression.
1289   * <p>
1290   * When properties in the clause are fully qualified as table-column names
1291   * then they are not translated. logical property name names (not fully
1292   * qualified) will still be translated to their physical name.
1293   * <p>
1294   * <h4>Examples:</h4>
1295   * <pre>{@code
1296   *
1297   *   // use a database function
1298   *   raw("add_days(orderDate, 10) < ?", someDate)
1299   *
1300   *   raw("name like ?", "Rob%")
1301   *
1302   *   raw("name in (?1)", asList("Rob", "Fiona", "Jack"))
1303   *
1304   *   raw("name = any(?)", asList("Rob", "Fiona", "Jack"))
1305   *
1306   * }</pre>
1307   *
1308   * <h4>Subquery examples:</h4>
1309   * <pre>{@code
1310   *
1311   *   // Bind collection using ?1
1312   *   .raw("id in (select c.id from o_customer c where c.name in (?1))", asList("Rob", "Fiona", "Jack"))
1313   *
1314   *   // Using Postgres ANY expression
1315   *   .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
1316   *
1317   * }</pre>
1318   */
1319  ExpressionList<T> raw(String raw, Object value);
1320
1321  /**
1322   * Add raw expression with an array of parameters.
1323   * <p>
1324   * The raw expression should contain the same number of ? or ?1, ?2 ... bind parameters
1325   * as there are values. We use ?1, ?2 etc when binding a collection for an IN expression.
1326   * <p>
1327   * When properties in the clause are fully qualified as table-column names
1328   * then they are not translated. logical property name names (not fully
1329   * qualified) will still be translated to their physical name.
1330   * </p>
1331   *
1332   * <h4>Examples:</h4>
1333   * <pre>{@code
1334   *
1335   *   raw("unitPrice > ? and product.id > ?", 2, 3)
1336   *
1337   *   raw("(status = ? or (orderDate < ? and shipDate is null) or customer.name like ?)",
1338   *         Order.Status.APPROVED,
1339   *         new Timestamp(System.currentTimeMillis()),
1340   *         "Rob")
1341   *
1342   * }</pre></pre>
1343   */
1344  ExpressionList<T> raw(String raw, Object... values);
1345
1346  /**
1347   * Add raw expression with no parameters.
1348   * <p>
1349   * When properties in the clause are fully qualified as table-column names
1350   * then they are not translated. logical property name names (not fully
1351   * qualified) will still be translated to their physical name.
1352   * </p>
1353   * <pre>{@code
1354   *
1355   *   raw("orderQty < shipQty")
1356   *
1357   * }</pre>
1358   *
1359   * <h4>Subquery example:</h4>
1360   * <pre>{@code
1361   *
1362   *   .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
1363   *
1364   * }</pre>
1365   */
1366  ExpressionList<T> raw(String raw);
1367
1368  /**
1369   * Only add the raw expression if the values is not null or empty.
1370   * <p>
1371   * This is a pure convenience expression to make it nicer to deal with the pattern where we use
1372   * raw() expression with a subquery and only want to add the subquery predicate when the collection
1373   * of values is not empty.
1374   * </p>
1375   * <h3>Without inOrEmpty()</h3>
1376   * <pre>{@code
1377   *
1378   *   query.where() // add some predicates
1379   *     .eq("status", Status.NEW);
1380   *
1381   *   // common pattern - we can use rawOrEmpty() instead
1382   *   if (orderIds != null && !orderIds.isEmpty()) {
1383   *     query.where().raw("t0.customer_id in (select o.customer_id from orders o where o.id in (?1))", orderIds);
1384   *   }
1385   *
1386   *   query.findList();
1387   *
1388   * }</pre>
1389   *
1390   * <h3>Using rawOrEmpty()</h3>
1391   * Note that in the example below we use the <code>?1</code> bind parameter to get  "parameter expansion"
1392   * for each element in the collection.
1393   *
1394   * <pre>{@code
1395   *
1396   *   query.where()
1397   *     .eq("status", Status.NEW)
1398   *     // only add the expression if orderIds is not empty
1399   *     .rawOrEmpty("t0.customer_id in (select o.customer_id from orders o where o.id in (?1))", orderIds);
1400   *     .findList();
1401   *
1402   * }</pre>
1403   *
1404   * <h3>Postgres ANY</h3>
1405   * With Postgres we would often use the SQL <code>ANY</code> expression and array parameter binding
1406   * rather than <code>IN</code>.
1407   *
1408   * <pre>{@code
1409   *
1410   *   query.where()
1411   *     .eq("status", Status.NEW)
1412   *     .rawOrEmpty("t0.customer_id in (select o.customer_id from orders o where o.id = any(?))", orderIds);
1413   *     .findList();
1414   *
1415   * }</pre>
1416   * <p>
1417   * Note that we need to cast the Postgres array for UUID types like:
1418   * </p>
1419   * <pre>{@code
1420   *
1421   *   " ... = any(?::uuid[])"
1422   *
1423   * }</pre>
1424   *
1425   * @param raw    The raw expression that is typically a subquery
1426   * @param values The values which is typically a list or set of id values.
1427   */
1428  ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
1429
1430  /**
1431   * Add a match expression.
1432   *
1433   * @param propertyName The property name for the match
1434   * @param search       The search value
1435   */
1436  ExpressionList<T> match(String propertyName, String search);
1437
1438  /**
1439   * Add a match expression with options.
1440   *
1441   * @param propertyName The property name for the match
1442   * @param search       The search value
1443   */
1444  ExpressionList<T> match(String propertyName, String search, Match options);
1445
1446  /**
1447   * Add a multi-match expression.
1448   */
1449  ExpressionList<T> multiMatch(String search, String... properties);
1450
1451  /**
1452   * Add a multi-match expression using options.
1453   */
1454  ExpressionList<T> multiMatch(String search, MultiMatch options);
1455
1456  /**
1457   * Add a simple query string expression.
1458   */
1459  ExpressionList<T> textSimple(String search, TextSimple options);
1460
1461  /**
1462   * Add a query string expression.
1463   */
1464  ExpressionList<T> textQueryString(String search, TextQueryString options);
1465
1466  /**
1467   * Add common terms expression.
1468   */
1469  ExpressionList<T> textCommonTerms(String search, TextCommonTerms options);
1470
1471  /**
1472   * And - join two expressions with a logical and.
1473   */
1474  ExpressionList<T> and(Expression expOne, Expression expTwo);
1475
1476  /**
1477   * Or - join two expressions with a logical or.
1478   */
1479  ExpressionList<T> or(Expression expOne, Expression expTwo);
1480
1481  /**
1482   * Negate the expression (prefix it with NOT).
1483   */
1484  ExpressionList<T> not(Expression exp);
1485
1486  /**
1487   * Start a list of expressions that will be joined by AND's
1488   * returning the expression list the expressions are added to.
1489   * <p>
1490   * This is exactly the same as conjunction();
1491   * </p>
1492   * <p>
1493   * Use endAnd() or endJunction() to end the AND junction.
1494   * </p>
1495   * <p>
1496   * Note that a where() clause defaults to an AND junction so
1497   * typically you only explicitly need to use the and() junction
1498   * when it is nested inside an or() or not() junction.
1499   * </p>
1500   * <pre>{@code
1501   *
1502   *  // Example: Nested and()
1503   *
1504   *    .where()
1505   *    .or()
1506   *      .and() // nested and
1507   *        .startsWith("name", "r")
1508   *        .eq("anniversary", onAfter)
1509   *        .endAnd()
1510   *      .and()
1511   *        .eq("status", Customer.Status.ACTIVE)
1512   *        .gt("id", 0)
1513   *        .endAnd()
1514   *      .order().asc("name")
1515   *      .findList();
1516   * }</pre>
1517   */
1518  Junction<T> and();
1519
1520  /**
1521   * Return a list of expressions that will be joined by OR's.
1522   * This is exactly the same as disjunction();
1523   * <p>
1524   * Use endOr() or endJunction() to end the OR junction.
1525   * </p>
1526   *
1527   * <pre>{@code
1528   *
1529   *  // Example: (status active OR anniversary is null)
1530   *
1531   *    .where()
1532   *    .or()
1533   *      .eq("status", Customer.Status.ACTIVE)
1534   *      .isNull("anniversary")
1535   *    .order().asc("name")
1536   *    .findList();
1537   *
1538   * }</pre>
1539   *
1540   * <pre>{@code
1541   *
1542   *  // Example: Use or() to join
1543   *  // two nested and() expressions
1544   *
1545   *    .where()
1546   *    .or()
1547   *      .and()
1548   *        .startsWith("name", "r")
1549   *        .eq("anniversary", onAfter)
1550   *        .endAnd()
1551   *      .and()
1552   *        .eq("status", Customer.Status.ACTIVE)
1553   *        .gt("id", 0)
1554   *        .endAnd()
1555   *      .order().asc("name")
1556   *      .findList();
1557   *
1558   * }</pre>
1559   */
1560  Junction<T> or();
1561
1562  /**
1563   * Return a list of expressions that will be wrapped by NOT.
1564   * <p>
1565   * Use endNot() or endJunction() to end expressions being added to the
1566   * NOT expression list.
1567   * </p>
1568   *
1569   * <pre>{@code
1570   *
1571   *    .where()
1572   *      .not()
1573   *        .gt("id", 1)
1574   *        .eq("anniversary", onAfter)
1575   *        .endNot()
1576   *
1577   * }</pre>
1578   *
1579   * <pre>{@code
1580   *
1581   * // Example: nested not()
1582   *
1583   *   .where()
1584   *     .eq("status", Customer.Status.ACTIVE)
1585   *     .not()
1586   *       .gt("id", 1)
1587   *       .eq("anniversary", onAfter)
1588   *       .endNot()
1589   *     .order()
1590   *       .asc("name")
1591   *     .findList();
1592   *
1593   * }</pre>
1594   */
1595  Junction<T> not();
1596
1597  /**
1598   * Start (and return) a list of expressions that will be joined by AND's.
1599   * <p>
1600   * This is the same as and().
1601   * </p>
1602   */
1603  Junction<T> conjunction();
1604
1605  /**
1606   * Start (and return) a list of expressions that will be joined by OR's.
1607   * <p>
1608   * This is the same as or().
1609   * </p>
1610   */
1611  Junction<T> disjunction();
1612
1613  /**
1614   * Start a list of expressions that will be joined by MUST.
1615   * <p>
1616   * This automatically makes the query a useDocStore(true) query that
1617   * will execute against the document store (ElasticSearch etc).
1618   * </p>
1619   * <p>
1620   * This is logically similar to and().
1621   * </p>
1622   */
1623  Junction<T> must();
1624
1625  /**
1626   * Start a list of expressions that will be joined by SHOULD.
1627   * <p>
1628   * This automatically makes the query a useDocStore(true) query that
1629   * will execute against the document store (ElasticSearch etc).
1630   * </p>
1631   * <p>
1632   * This is logically similar to or().
1633   * </p>
1634   */
1635  Junction<T> should();
1636
1637  /**
1638   * Start a list of expressions that will be joined by MUST NOT.
1639   * <p>
1640   * This automatically makes the query a useDocStore(true) query that
1641   * will execute against the document store (ElasticSearch etc).
1642   * </p>
1643   * <p>
1644   * This is logically similar to not().
1645   * </p>
1646   */
1647  Junction<T> mustNot();
1648
1649  /**
1650   * End a junction returning the parent expression list.
1651   * <p>
1652   * Ends a and(), or(), not(), must(), mustNot() or should() junction
1653   * such that you get the parent expression.
1654   * </p>
1655   * <p>
1656   * Alternatively you can always use where() to return the top level expression list.
1657   * </p>
1658   */
1659  ExpressionList<T> endJunction();
1660
1661  /**
1662   * End a AND junction - synonym for endJunction().
1663   */
1664  ExpressionList<T> endAnd();
1665
1666  /**
1667   * End a AND junction - synonym for endJunction().
1668   */
1669  ExpressionList<T> endOr();
1670
1671  /**
1672   * End a NOT junction - synonym for endJunction().
1673   */
1674  ExpressionList<T> endNot();
1675
1676}