Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / search / Query.java
blob4e48b2f7bf03503f705999c52db2ade68a780d92
1 // Copyright 2010 Google Inc. All Rights Reserved.
3 package com.google.appengine.api.search;
5 import com.google.appengine.api.search.SearchServicePb.SearchParams;
6 import com.google.appengine.api.search.checkers.Preconditions;
7 import com.google.appengine.api.search.checkers.QueryChecker;
9 /**
10 * A query to search an index for documents which match,
11 * restricting the document fields returned to those given, and
12 * scoring and sorting the results, whilst supporting pagination.
13 * <p>
14 * For example, the following query will search for documents where
15 * the tokens 'good' and 'story' occur in some fields,
16 * returns up to 20 results including the fields 'author' and 'date-sent'
17 * as well as snippeted fields 'subject' and 'body'. The results
18 * are sorted by 'author' in descending order, getting the next 20 results
19 * from the responseCursor in the previously returned results, giving
20 * back a single cursor in the {@link Results} to get the next
21 * batch of results after this.
22 * <p>
23 * <pre>
24 * QueryOptions options = QueryOptions.newBuilder()
25 * .setLimit(20)
26 * .setFieldsToSnippet("subject", "body")
27 * .setScorer(CustomScorer.newBuilder()
28 * .addSortExpression(SortExpression.newBuilder()
29 * .setExpression("author")
30 * .setDirection(SortDirection.DESCENDING)
31 * .setDefaultValue("")))
32 * .setCursor(responseCursor)
33 * .build();
34 * Query query = Query.newBuilder()
35 * .setOptions(options)
36 * .build("good story");
37 * </pre>
40 public class Query {
42 /**
43 * A builder which constructs Query objects.
45 public static class Builder {
46 private String queryString;
47 private QueryOptions options;
49 protected Builder() {
52 /**
53 * Constructs a {@link Query} builder with the given query.
55 * @param query the query to populate the builder
57 private Builder(Query query) {
58 this.queryString = query.getQueryString();
59 this.options = query.getOptions();
62 /**
63 * Sets the query options.
65 * @param options the {@link QueryOptions} to apply to the search results
66 * @return this builder
68 public Builder setOptions(QueryOptions options) {
69 this.options = options;
70 return this;
73 /**
74 * Sets the query options from a builder.
76 * @param optionsBuilder the {@link QueryOptions.Builder} build a
77 * {@link QueryOptions{ to apply to the search results
78 * @return this builder
80 public Builder setOptions(QueryOptions.Builder optionsBuilder) {
81 return setOptions(optionsBuilder.build());
84 /**
85 * Sets the query string used to construct the query.
87 * @param query a query string used to construct the query
88 * @return this Builder
89 * @throws SearchQueryException if the query string does not parse
91 protected Builder setQueryString(String query) {
92 this.queryString = QueryChecker.checkQuery(query);
93 return this;
96 /**
97 * Build a {@link Query} from the query string and the parameters set on
98 * the {@link Builder}. A query string can be as simple as a single term
99 * ("foo"), or as complex as a boolean expression, including field names
100 * ("title:hello OR body:important -october").
102 * @param queryString the query string to parse and apply to an index
103 * @return the Query built from the parameters entered on this
104 * Builder including the queryString
105 * @throws SearchQueryException if the query string is invalid
107 public Query build(String queryString) {
108 setQueryString(queryString);
109 return new Query(this);
113 * Construct the message.
115 * @return the Query built from the parameters entered on this
116 * Builder
117 * @throws IllegalArgumentException if the query string is invalid
119 public Query build() {
120 return new Query(this);
124 private final String query;
125 private final QueryOptions options;
128 * Creates a query from the builder.
130 * @param builder the query builder to populate with
132 protected Query(Builder builder) {
133 query = builder.queryString;
134 options = builder.options;
135 checkValid();
139 * The query can be as simple as a single term ("foo"), or as complex
140 * as a boolean expression, including field names ("title:hello OR
141 * body:important -october").
143 * @return the query
145 public String getQueryString() {
146 return query;
150 * @return the {@link QueryOptions} for controlling the what is returned
151 * in the result set matching the query
153 public QueryOptions getOptions() {
154 return options;
158 * Creates and returns a {@link Query} builder. Set the query
159 * parameters and use the {@link Builder#build()} method to create a concrete
160 * instance of Query.
162 * @return a {@link Builder} which can construct a query
164 public static Builder newBuilder() {
165 return new Builder();
169 * Creates a builder from the given query.
171 * @param query the query for the builder to use to build another query
172 * @return a new builder with values based on the given request
174 public static Builder newBuilder(Query query) {
175 return new Builder(query);
179 * Checks the query is valid, specifically, has a non-null
180 * query string.
182 * @return this checked Query
183 * @throws NullPointerException if query is null
185 private Query checkValid() {
186 Preconditions.checkNotNull(query, "query cannot be null");
187 return this;
191 * Copies the contents of this {@link Query} object into a
192 * {@link SearchParams} protocol buffer builder.
194 * @return a search params protocol buffer builder initialized with
195 * the values from this query
196 * @throws IllegalArgumentException if the cursor type is
197 * unknown
199 SearchParams.Builder copyToProtocolBuffer() {
200 SearchParams.Builder builder = SearchParams.newBuilder().setQuery(query);
201 if (options == null) {
202 QueryOptions.newBuilder().build().copyToProtocolBuffer(builder, query);
203 } else {
204 options.copyToProtocolBuffer(builder, query);
206 return builder;
209 @Override
210 public String toString() {
211 return String.format(
212 "Query(queryString=%s%s)",
213 query,
214 Util.fieldToString("options", options));