001package com.avaje.ebean;
002
003import com.avaje.ebean.search.Match;
004import com.avaje.ebean.search.MultiMatch;
005import com.avaje.ebean.search.TextCommonTerms;
006import com.avaje.ebean.search.TextQueryString;
007import com.avaje.ebean.search.TextSimple;
008import org.jetbrains.annotations.Nullable;
009
010import javax.persistence.NonUniqueResultException;
011import java.sql.Timestamp;
012import java.util.Collection;
013import java.util.List;
014import java.util.Map;
015import java.util.Set;
016
017/**
018 * List of Expressions that make up a where or having clause.
019 * <p>
020 * An ExpressionList is returned from {@link Query#where()}.
021 * </p>
022 * <p>
023 * The ExpressionList has a list of convenience methods that create the standard
024 * expressions and add them to this list.
025 * </p>
026 * <p>
027 * The ExpressionList also duplicates methods that are found on the Query such
028 * as findList() and orderBy(). The purpose of these methods is provide a fluid
029 * API. The upside of this approach is that you can build and execute a query
030 * via chained methods. The down side is that this ExpressionList object has
031 * more methods than you would initially expect (the ones duplicated from
032 * Query).
033 * </p>
034 * 
035 * @see Query#where()
036 */
037public interface ExpressionList<T> {
038
039  /**
040   * Return the query that owns this expression list.
041   * <p>
042   * This is a convenience method solely to support a fluid API where the
043   * methods are chained together. Adding expressions returns this expression
044   * list and this method can be used after that to return back the original
045   * query so that further things can be added to it.
046   * </p>
047   */
048  Query<T> query();
049
050  /**
051   * Set the order by clause replacing the existing order by clause if there is
052   * one.
053   * <p>
054   * This follows SQL syntax using commas between each property with the
055   * optional asc and desc keywords representing ascending and descending order
056   * respectively.
057   * </p>
058   * <p>
059   * This is EXACTLY the same as {@link #orderBy(String)}.
060   * </p>
061   */
062  Query<T> order(String orderByClause);
063
064  /**
065   * Return the OrderBy so that you can append an ascending or descending
066   * property to the order by clause.
067   * <p>
068   * This will never return a null. If no order by clause exists then an 'empty'
069   * OrderBy object is returned.
070   * </p>
071   */
072  OrderBy<T> order();
073
074  /**
075   * Return the OrderBy so that you can append an ascending or descending
076   * property to the order by clause.
077   * <p>
078   * This will never return a null. If no order by clause exists then an 'empty'
079   * OrderBy object is returned.
080   * </p>
081   */
082  OrderBy<T> orderBy();
083
084  /**
085   * Add an orderBy clause to the query.
086   * 
087   * @see Query#orderBy(String)
088   */
089  Query<T> orderBy(String orderBy);
090
091  /**
092   * Add an orderBy clause to the query.
093   * 
094   * @see Query#orderBy(String)
095   */
096  Query<T> setOrderBy(String orderBy);
097
098  /**
099   * Apply the path properties to the query replacing the select and fetch clauses.
100   */
101  Query<T> apply(FetchPath fetchPath);
102
103  /**
104   * Perform an 'As of' query using history tables to return the object graph
105   * as of a time in the past.
106   * <p>
107   *   To perform this query the DB must have underlying history tables.
108   * </p>
109   *
110   * @param asOf the date time in the past at which you want to view the data
111   */
112  Query<T> asOf(Timestamp asOf);
113
114  /**
115   * Execute the query against the draft set of tables.
116   */
117  Query<T> asDraft();
118
119  /**
120   * Deprecated in favour of setIncludeSoftDeletes().
121   */
122  @Deprecated
123  Query<T> includeSoftDeletes();
124
125  /**
126   * Execute the query including soft deleted rows.
127   */
128  Query<T> setIncludeSoftDeletes();
129
130  /**
131   * Execute as a delete query deleting the 'root level' beans that match the predicates
132   * in the query.
133   * <p>
134   * Note that if the query includes joins then the generated delete statement may not be
135   * optimal depending on the database platform.
136   * </p>
137   *
138   * @return the number of rows that were deleted.
139   */
140  int delete();
141
142  /**
143   * Execute as a update query.
144   *
145   * @return the number of rows that were updated.
146   * @see UpdateQuery
147   */
148  int update();
149
150  /**
151   * Execute the query process the beans one at a time.
152   *
153   * @see Query#findEach(QueryEachConsumer)
154   */
155  void findEach(QueryEachConsumer<T> consumer);
156
157  /**
158   * Execute the query processing the beans one at a time with the ability to
159   * stop processing before reading all the beans.
160   *
161   * @see Query#findEachWhile(QueryEachWhileConsumer)
162   */
163  void findEachWhile(QueryEachWhileConsumer<T> consumer);
164
165  /**
166   * Execute the query returning a list.
167   * 
168   * @see Query#findList()
169   */
170  List<T> findList();
171
172  /**
173   * Execute the query returning the list of Id's.
174   * 
175   * @see Query#findIds()
176   */
177  List<Object> findIds();
178
179  /**
180   * Return the count of entities this query should return.
181   * <p>
182   * This is the number of 'top level' or 'root level' entities.
183   * </p>
184   */
185  int findCount();
186
187  /**
188   * Deprecated in favor of findCount().
189   *
190   * @deprecated
191   */
192  int findRowCount();
193
194  /**
195   * Execute the query returning a set.
196   * 
197   * @see Query#findSet()
198   */
199  Set<T> findSet();
200
201  /**
202   * Execute the query returning a map.
203   * 
204   * @see Query#findMap()
205   */
206  Map<?, T> findMap();
207
208  /**
209   * Return a typed map specifying the key property and type.
210   */
211  <K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
212
213  /**
214   * Execute the query returning a single bean or null (if no matching
215   * bean is found).
216   * <p>
217   * If more than 1 row is found for this query then a NonUniqueResultException is
218   * thrown.
219   * </p>
220   *
221   * @throws NonUniqueResultException if more than one result was found
222   *
223   * @see Query#findUnique()
224   */
225  @Nullable
226  T findUnique();
227
228  /**
229   * Execute find row count query in a background thread.
230   * <p>
231   * This returns a Future object which can be used to cancel, check the
232   * execution status (isDone etc) and get the value (with or without a
233   * timeout).
234   * </p>
235   * 
236   * @return a Future object for the row count query
237   */
238  FutureRowCount<T> findFutureCount();
239
240  /**
241   * Deprecated in favor of findFutureCount().
242   *
243   * @deprecated
244   */
245  FutureRowCount<T> findFutureRowCount();
246
247  /**
248   * Execute find Id's query in a background thread.
249   * <p>
250   * This returns a Future object which can be used to cancel, check the
251   * execution status (isDone etc) and get the value (with or without a
252   * timeout).
253   * </p>
254   * 
255   * @return a Future object for the list of Id's
256   */
257  FutureIds<T> findFutureIds();
258
259  /**
260   * Execute find list query in a background thread.
261   * <p>
262   * This returns a Future object which can be used to cancel, check the
263   * execution status (isDone etc) and get the value (with or without a
264   * timeout).
265   * </p>
266   * 
267   * @return a Future object for the list result of the query
268   */
269  FutureList<T> findFutureList();
270
271  /**
272   * Return a PagedList for this query using firstRow and maxRows.
273   * <p>
274   * The benefit of using this over findList() is that it provides functionality to get the
275   * total row count etc.
276   * </p>
277   * <p>
278   * If maxRows is not set on the query prior to calling findPagedList() then a
279   * PersistenceException is thrown.
280   * </p>
281   *
282   * <pre>{@code
283   *
284   *  PagedList<Order> pagedList = Ebean.find(Order.class)
285   *       .setFirstRow(50)
286   *       .setMaxRows(20)
287   *       .findPagedList();
288   *
289   *       // fetch the total row count in the background
290   *       pagedList.loadRowCount();
291   *
292   *       List<Order> orders = pagedList.getList();
293   *       int totalRowCount = pagedList.getTotalRowCount();
294   *
295   * }</pre>
296   *
297   * @return The PagedList
298   *
299   * @see Query#findPagedList()
300   */
301  PagedList<T> findPagedList();
302
303  /**
304   * Return versions of a @History entity bean.
305   * <p>
306   *   Generally this query is expected to be a find by id or unique predicates query.
307   *   It will execute the query against the history returning the versions of the bean.
308   * </p>
309   */
310  List<Version<T>> findVersions();
311
312  /**
313   * Return versions of a @History entity bean between the 2 timestamps.
314   * <p>
315   *   Generally this query is expected to be a find by id or unique predicates query.
316   *   It will execute the query against the history returning the versions of the bean.
317   * </p>
318   */
319  List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
320
321  /**
322   * Add some filter predicate expressions to the many property.
323   */
324  ExpressionList<T> filterMany(String prop);
325
326  /**
327   * Specify specific properties to fetch on the main/root bean (aka partial
328   * object).
329   * 
330   * @see Query#select(String)
331   */
332  Query<T> select(String properties);
333
334  /**
335   * Set whether this query uses DISTINCT.
336   * <p>
337   * The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
338   * generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
339   * </p>
340   * <pre>{@code
341   *
342   *   List<Customer> customers =
343   *       Ebean.find(Customer.class)
344   *          .setDistinct(true)
345   *          .select("name")     // only select the customer name
346   *          .findList();
347   *
348   * }</pre>
349   */
350  Query<T> setDistinct(boolean distinct);
351
352  /**
353   * Set the first row to fetch.
354   * 
355   * @see Query#setFirstRow(int)
356   */
357  Query<T> setFirstRow(int firstRow);
358
359  /**
360   * Set the maximum number of rows to fetch.
361   * 
362   * @see Query#setMaxRows(int)
363   */
364  Query<T> setMaxRows(int maxRows);
365
366  /**
367   * Set the name of the property which values become the key of a map.
368   * 
369   * @see Query#setMapKey(String)
370   */
371  Query<T> setMapKey(String mapKey);
372
373  /**
374   * Set to true to use the query for executing this query.
375   * 
376   * @see Query#setUseCache(boolean)
377   */
378  Query<T> setUseCache(boolean useCache);
379
380  /**
381   * Set to true to use the query for executing this query.
382   *
383   * @see Query#setUseQueryCache(boolean)
384   */
385  Query<T> setUseQueryCache(boolean useCache);
386
387  /**
388   * Set to true if this query should execute against the doc store.
389   * <p>
390   * When setting this you may also consider disabling lazy loading.
391   * </p>
392   */
393  Query<T> setUseDocStore(boolean useDocsStore);
394
395  /**
396   * Set true if you want to disable lazy loading.
397   * <p>
398   * That is, once the object graph is returned further lazy loading is disabled.
399   * </p>
400   */
401  Query<T> setDisableLazyLoading(boolean disableLazyLoading);
402
403  /**
404   * Disable read auditing for this query.
405   * <p>
406   * This is intended to be used when the query is not a user initiated query and instead
407   * part of the internal processing in an application to load a cache or document store etc.
408   * In these cases we don't want the query to be part of read auditing.
409   * </p>
410   */
411  Query<T> setDisableReadAuditing();
412
413  /**
414   * Add expressions to the having clause.
415   * <p>
416   * The having clause is only used for queries based on raw sql (via SqlSelect
417   * annotation etc).
418   * </p>
419   */
420  ExpressionList<T> having();
421
422  /**
423   * Add another expression to the where clause.
424   */
425  ExpressionList<T> where();
426
427  /**
428   * Path exists - for the given path in a JSON document.
429   *
430   * <pre>{@code
431   *
432   *   where().jsonExists("content", "path.other")
433   *
434   * }</pre>
435   *
436   * @param propertyName the property that holds a JSON document
437   * @param path the nested path in the JSON document in dot notation
438   */
439  ExpressionList<T> jsonExists(String propertyName, String path);
440
441  /**
442   * Path does not exist - for the given path in a JSON document.
443   *
444   * <pre>{@code
445   *
446   *   where().jsonNotExists("content", "path.other")
447   *
448   * }</pre>
449   *
450   * @param propertyName the property that holds a JSON document
451   * @param path the nested path in the JSON document in dot notation
452   */
453  ExpressionList<T> jsonNotExists(String propertyName, String path);
454
455  /**
456   * Equal to expression for the value at the given path in the JSON document.
457   *
458   * <pre>{@code
459   *
460   *   where().jsonEqualTo("content", "path.other", 34)
461   *
462   * }</pre>
463   *
464   * @param propertyName the property that holds a JSON document
465   * @param path the nested path in the JSON document in dot notation
466   * @param value the value used to test against the document path's value
467   */
468  ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value);
469
470  /**
471   * Not Equal to - for the given path in a JSON document.
472   *
473   * <pre>{@code
474   *
475   *   where().jsonNotEqualTo("content", "path.other", 34)
476   *
477   * }</pre>
478   *
479   * @param propertyName the property that holds a JSON document
480   * @param path the nested path in the JSON document in dot notation
481   * @param value the value used to test against the document path's value
482   */
483  ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value);
484
485  /**
486   * Greater than - for the given path in a JSON document.
487   *
488   * <pre>{@code
489   *
490   *   where().jsonGreaterThan("content", "path.other", 34)
491   *
492   * }</pre>
493   */
494  ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object value);
495
496  /**
497   * Greater than or equal to - for the given path in a JSON document.
498   *
499   * <pre>{@code
500   *
501   *   where().jsonGreaterOrEqual("content", "path.other", 34)
502   *
503   * }</pre>
504   */
505  ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object value);
506
507  /**
508   * Less than - for the given path in a JSON document.
509   *
510   * <pre>{@code
511   *
512   *   where().jsonLessThan("content", "path.other", 34)
513   *
514   * }</pre>
515   */
516  ExpressionList<T> jsonLessThan(String propertyName, String path, Object value);
517
518  /**
519   * Less than or equal to - for the given path in a JSON document.
520   *
521   * <pre>{@code
522   *
523   *   where().jsonLessOrEqualTo("content", "path.other", 34)
524   *
525   * }</pre>
526   */
527  ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object value);
528
529  /**
530   * Between - for the given path in a JSON document.
531   *
532   * <pre>{@code
533   *
534   *   where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime)
535   *
536   * }</pre>
537   */
538  ExpressionList<T> jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
539
540  /**
541   * Add an Expression to the list.
542   * <p>
543   * This returns the list so that add() can be chained.
544   * </p>
545   *
546   * <pre>{@code
547   *
548   * Query<Customer> query = Ebean.find(Customer.class);
549   * query.where()
550   *     .like("name","Rob%")
551   *     .eq("status", Customer.ACTIVE);
552   *
553   * List<Customer> list = query.findList();
554   * ...
555   *
556   * }</pre>
557   */
558  ExpressionList<T> add(Expression expr);
559
560  /**
561   * Add a list of Expressions to this ExpressionList.s
562   */
563  ExpressionList<T> addAll(ExpressionList<T> exprList);
564
565  /**
566   * Equal To - property is equal to a given value.
567   */
568  ExpressionList<T> eq(String propertyName, Object value);
569
570  /**
571   * Not Equal To - property not equal to the given value.
572   */
573  ExpressionList<T> ne(String propertyName, Object value);
574
575  /**
576   * Case Insensitive Equal To - property equal to the given value (typically
577   * using a lower() function to make it case insensitive).
578   */
579  ExpressionList<T> ieq(String propertyName, String value);
580
581  /**
582   * Between - property between the two given values.
583   */
584  ExpressionList<T> between(String propertyName, Object value1, Object value2);
585
586  /**
587   * Between - value between the two properties.
588   */
589  ExpressionList<T> betweenProperties(String lowProperty, String highProperty, Object value);
590
591  /**
592   * Greater Than - property greater than the given value.
593   */
594  ExpressionList<T> gt(String propertyName, Object value);
595
596  /**
597   * Greater Than or Equal to - property greater than or equal to the given
598   * value.
599   */
600  ExpressionList<T> ge(String propertyName, Object value);
601
602  /**
603   * Less Than - property less than the given value.
604   */
605  ExpressionList<T> lt(String propertyName, Object value);
606
607  /**
608   * Less Than or Equal to - property less than or equal to the given value.
609   */
610  ExpressionList<T> le(String propertyName, Object value);
611
612  /**
613   * Is Null - property is null.
614   */
615  ExpressionList<T> isNull(String propertyName);
616
617  /**
618   * Is Not Null - property is not null.
619   */
620  ExpressionList<T> isNotNull(String propertyName);
621
622  /**
623   * A "Query By Example" type of expression.
624   * <p>
625   * Pass in an example entity and for each non-null scalar properties an
626   * expression is added.
627   * </p>
628   * <p>
629   * By Default this case sensitive, will ignore numeric zero values and will
630   * use a Like for string values (you must put in your own wildcards).
631   * </p>
632   * <p>
633   * To get control over the options you can create an ExampleExpression and set
634   * those options such as case insensitive etc.
635   * </p>
636   * 
637   * <pre>{@code
638   *
639   * // create an example bean and set the properties
640   * // with the query parameters you want
641   * Customer example = new Customer();
642   * example.setName("Rob%");
643   * example.setNotes("%something%");
644   * 
645   * List&lt;Customer&gt; list = Ebean.find(Customer.class).where()
646   *     // pass the bean into the where() clause
647   *     .exampleLike(example)
648   *     // you can add other expressions to the same query
649   *     .gt("id", 2).findList();
650   * 
651   * }</pre>
652   * 
653   * Similarly you can create an ExampleExpression
654   * 
655   * <pre>{@code
656   *
657   * Customer example = new Customer();
658   * example.setName("Rob%");
659   * example.setNotes("%something%");
660   * 
661   * // create a ExampleExpression with more control
662   * ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros();
663   * 
664   * List<Customer> list = Ebean.find(Customer.class).where().add(qbe).findList();
665   *
666   * }</pre>
667   */
668  ExpressionList<T> exampleLike(Object example);
669
670  /**
671   * Case insensitive version of {@link #exampleLike(Object)}
672   */
673  ExpressionList<T> iexampleLike(Object example);
674
675  /**
676   * Like - property like value where the value contains the SQL wild card
677   * characters % (percentage) and _ (underscore).
678   */
679  ExpressionList<T> like(String propertyName, String value);
680
681  /**
682   * Case insensitive Like - property like value where the value contains the
683   * SQL wild card characters % (percentage) and _ (underscore). Typically uses
684   * a lower() function to make the expression case insensitive.
685   */
686  ExpressionList<T> ilike(String propertyName, String value);
687
688  /**
689   * Starts With - property like value%.
690   */
691  ExpressionList<T> startsWith(String propertyName, String value);
692
693  /**
694   * Case insensitive Starts With - property like value%. Typically uses a
695   * lower() function to make the expression case insensitive.
696   */
697  ExpressionList<T> istartsWith(String propertyName, String value);
698
699  /**
700   * Ends With - property like %value.
701   */
702  ExpressionList<T> endsWith(String propertyName, String value);
703
704  /**
705   * Case insensitive Ends With - property like %value. Typically uses a lower()
706   * function to make the expression case insensitive.
707   */
708  ExpressionList<T> iendsWith(String propertyName, String value);
709
710  /**
711   * Contains - property like %value%.
712   */
713  ExpressionList<T> contains(String propertyName, String value);
714
715  /**
716   * Case insensitive Contains - property like %value%. Typically uses a lower()
717   * function to make the expression case insensitive.
718   */
719  ExpressionList<T> icontains(String propertyName, String value);
720
721  /**
722   * In - using a subQuery.
723   */
724  ExpressionList<T> in(String propertyName, Query<?> subQuery);
725
726  /**
727   * In - property has a value in the array of values.
728   */
729  ExpressionList<T> in(String propertyName, Object... values);
730
731  /**
732   * In - property has a value in the collection of values.
733   */
734  ExpressionList<T> in(String propertyName, Collection<?> values);
735
736  /**
737   * Not In - property has a value in the array of values.
738   */
739  ExpressionList<T> notIn(String propertyName, Object... values);
740
741  /**
742   * Not In - property has a value in the collection of values.
743   */
744  ExpressionList<T> notIn(String propertyName, Collection<?> values);
745
746  /**
747   * Not In - using a subQuery.
748   */
749  ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
750
751  /**
752   * Is empty expression for collection properties.
753   */
754  ExpressionList<T> isEmpty(String propertyName);
755
756  /**
757   * Is not empty expression for collection properties.
758   */
759  ExpressionList<T> isNotEmpty(String propertyName);
760
761  /**
762   * Exists expression
763   */
764  ExpressionList<T> exists(Query<?> subQuery);
765  
766  /**
767   * Not exists expression
768   */
769  ExpressionList<T> notExists(Query<?> subQuery);
770
771  /**
772   * Id IN a list of id values.
773   */
774  ExpressionList<T> idIn(Object... idValues);
775
776  /**
777   * Id IN a list of id values.
778   */
779  ExpressionList<T> idIn(List<?> idValues);
780
781  /**
782   * Id Equal to - ID property is equal to the value.
783   */
784  ExpressionList<T> idEq(Object value);
785
786  /**
787   * All Equal - Map containing property names and their values.
788   * <p>
789   * Expression where all the property names in the map are equal to the
790   * corresponding value.
791   * </p>
792   * 
793   * @param propertyMap
794   *          a map keyed by property names.
795   */
796  ExpressionList<T> allEq(Map<String, Object> propertyMap);
797
798  /**
799   * Array property contains entries with the given values.
800   */
801  ExpressionList<T> arrayContains(String propertyName, Object... values);
802
803  /**
804   * Array does not contain the given values.
805   * <p>
806   * Array support is effectively limited to Postgres at this time.
807   * </p>
808   */
809  ExpressionList<T> arrayNotContains(String propertyName, Object... values);
810
811  /**
812   * Array is empty - for the given array property.
813   * <p>
814   * Array support is effectively limited to Postgres at this time.
815   * </p>
816   */
817  ExpressionList<T> arrayIsEmpty(String propertyName);
818
819  /**
820   * Array is not empty - for the given array property.
821   * <p>
822   * Array support is effectively limited to Postgres at this time.
823   * </p>
824   */
825  ExpressionList<T> arrayIsNotEmpty(String propertyName);
826
827  /**
828   * Add raw expression with a single parameter.
829   * <p>
830   * The raw expression should contain a single ? at the location of the
831   * parameter.
832   * </p>
833   * <p>
834   * When properties in the clause are fully qualified as table-column names
835   * then they are not translated. logical property name names (not fully
836   * qualified) will still be translated to their physical name.
837   * </p>
838   *
839   * <h4>Example:</h4>
840   * <pre>{@code
841   *
842   *   // use a database function
843   *   raw("add_days(orderDate, 10) < ?", someDate)
844   *
845   * }</pre>
846   */
847  ExpressionList<T> raw(String raw, Object value);
848
849  /**
850   * Add raw expression with an array of parameters.
851   * <p>
852   * The raw expression should contain the same number of ? as there are
853   * parameters.
854   * </p>
855   * <p>
856   * When properties in the clause are fully qualified as table-column names
857   * then they are not translated. logical property name names (not fully
858   * qualified) will still be translated to their physical name.
859   * </p>
860   */
861  ExpressionList<T> raw(String raw, Object... values);
862
863  /**
864   * Add raw expression with no parameters.
865   * <p>
866   * When properties in the clause are fully qualified as table-column names
867   * then they are not translated. logical property name names (not fully
868   * qualified) will still be translated to their physical name.
869   * </p>
870   *
871   * <pre>{@code
872   *
873   *   raw("orderQty < shipQty")
874   *
875   * }</pre>
876   */
877  ExpressionList<T> raw(String raw);
878
879  /**
880   * Add a match expression.
881   *
882   * @param propertyName The property name for the match
883   * @param search The search value
884   */
885  ExpressionList<T> match(String propertyName, String search);
886
887  /**
888   * Add a match expression with options.
889   *
890   * @param propertyName The property name for the match
891   * @param search The search value
892   */
893  ExpressionList<T> match(String propertyName, String search, Match options);
894
895  /**
896   * Add a multi-match expression.
897   */
898  ExpressionList<T>  multiMatch(String search, String... properties);
899
900  /**
901   * Add a multi-match expression using options.
902   */
903  ExpressionList<T> multiMatch(String search, MultiMatch options);
904
905  /**
906   * Add a simple query string expression.
907   */
908  ExpressionList<T> textSimple(String search, TextSimple options);
909
910  /**
911   * Add a query string expression.
912   */
913  ExpressionList<T> textQueryString(String search, TextQueryString options);
914
915  /**
916   * Add common terms expression.
917   */
918  ExpressionList<T> textCommonTerms(String search, TextCommonTerms options);
919
920  /**
921   * And - join two expressions with a logical and.
922   */
923  ExpressionList<T> and(Expression expOne, Expression expTwo);
924
925  /**
926   * Or - join two expressions with a logical or.
927   */
928  ExpressionList<T> or(Expression expOne, Expression expTwo);
929
930  /**
931   * Negate the expression (prefix it with NOT).
932   */
933  ExpressionList<T> not(Expression exp);
934
935  /**
936   * Start a list of expressions that will be joined by AND's
937   * returning the expression list the expressions are added to.
938   * <p>
939   * This is exactly the same as conjunction();
940   * </p>
941   * <p>
942   * Use endAnd() or endJunction() to end the AND junction.
943   * </p>
944   * <p>
945   * Note that a where() clause defaults to an AND junction so
946   * typically you only explicitly need to use the and() junction
947   * when it is nested inside an or() or not() junction.
948   * </p>
949   *
950   * <pre>{@code
951   *
952   *  // Example: Nested and()
953   *
954   *  Ebean.find(Customer.class)
955   *    .where()
956   *    .or()
957   *      .and() // nested and
958   *        .startsWith("name", "r")
959   *        .eq("anniversary", onAfter)
960   *        .endAnd()
961   *      .and()
962   *        .eq("status", Customer.Status.ACTIVE)
963   *        .gt("id", 0)
964   *        .endAnd()
965   *      .orderBy().asc("name")
966   *      .findList();
967   * }</pre>
968   */
969  Junction<T> and();
970
971  /**
972   * Return a list of expressions that will be joined by OR's.
973   * This is exactly the same as disjunction();
974   *
975   * <p>
976   *   Use endOr() or endJunction() to end the OR junction.
977   * </p>
978   *
979   * <pre>{@code
980   *
981   *  // Example: Use or() to join
982   *  // two nested and() expressions
983   *
984   *  Ebean.find(Customer.class)
985   *    .where()
986   *    .or()
987   *      .and()
988   *        .startsWith("name", "r")
989   *        .eq("anniversary", onAfter)
990   *        .endAnd()
991   *      .and()
992   *        .eq("status", Customer.Status.ACTIVE)
993   *        .gt("id", 0)
994   *        .endAnd()
995   *      .orderBy().asc("name")
996   *      .findList();
997   *
998   * }</pre>
999   */
1000  Junction<T> or();
1001
1002  /**
1003   * Return a list of expressions that will be wrapped by NOT.
1004   * <p>
1005   *   Use endNot() or endJunction() to end expressions being added to the
1006   *   NOT expression list.
1007   * </p>
1008   *
1009   * <pre>@{code
1010   *
1011   *    .where()
1012   *      .not()
1013   *        .gt("id", 1)
1014   *        .eq("anniversary", onAfter)
1015   *        .endNot()
1016   *
1017   * }</pre>
1018   *
1019   * <pre>@{code
1020   *
1021   * // Example: nested not()
1022   *
1023   * Ebean.find(Customer.class)
1024   *   .where()
1025   *     .eq("status", Customer.Status.ACTIVE)
1026   *     .not()
1027   *       .gt("id", 1)
1028   *       .eq("anniversary", onAfter)
1029   *       .endNot()
1030   *     .orderBy()
1031   *       .asc("name")
1032   *     .findList();
1033   *
1034   * }</pre>
1035   */
1036  Junction<T> not();
1037
1038  /**
1039   * Start (and return) a list of expressions that will be joined by AND's.
1040   * <p>
1041   * This is the same as and().
1042   * </p>
1043   */
1044  Junction<T> conjunction();
1045
1046  /**
1047   * Start (and return) a list of expressions that will be joined by OR's.
1048   * <p>
1049   * This is the same as or().
1050   * </p>
1051   */
1052  Junction<T> disjunction();
1053
1054  /**
1055   * Start a list of expressions that will be joined by MUST.
1056   * <p>
1057   * This automatically makes the query a useDocStore(true) query that
1058   * will execute against the document store (ElasticSearch etc).
1059   * </p>
1060   * <p>
1061   * This is logically similar to and().
1062   * </p>
1063   */
1064  Junction<T> must();
1065
1066  /**
1067   * Start a list of expressions that will be joined by SHOULD.
1068   * <p>
1069   * This automatically makes the query a useDocStore(true) query that
1070   * will execute against the document store (ElasticSearch etc).
1071   * </p>
1072   * <p>
1073   * This is logically similar to or().
1074   * </p>
1075   */
1076  Junction<T> should();
1077
1078  /**
1079   * Start a list of expressions that will be joined by MUST NOT.
1080   * <p>
1081   * This automatically makes the query a useDocStore(true) query that
1082   * will execute against the document store (ElasticSearch etc).
1083   * </p>
1084   * <p>
1085   * This is logically similar to not().
1086   * </p>
1087   */
1088  Junction<T> mustNot();
1089
1090  /**
1091   * End a junction returning the parent expression list.
1092   * <p>
1093   * Ends a and(), or(), not(), must(), mustNot() or should() junction
1094   * such that you get the parent expression.
1095   * </p>
1096   * <p>
1097   * Alternatively you can always use where() to return the top level expression list.
1098   * </p>
1099   */
1100  ExpressionList<T> endJunction();
1101
1102  /**
1103   * End a AND junction - synonym for endJunction().
1104   */
1105  ExpressionList<T> endAnd();
1106
1107  /**
1108   * End a AND junction - synonym for endJunction().
1109   */
1110  ExpressionList<T> endOr();
1111
1112  /**
1113   * End a NOT junction - synonym for endJunction().
1114   */
1115  ExpressionList<T> endNot();
1116
1117}