App Engine Java SDK version 1.9.8
[gae.git] / java / src / main / com / google / appengine / api / search / Query.java
blob4aadedf3409fc0c5bfcc0f3448aba40ebe864f68
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>
39 public class Query {
41 /**
42 * A builder which constructs Query objects.
44 public static class Builder {
45 private String queryString;
46 private QueryOptions options;
48 protected Builder() {
51 /**
52 * Constructs a {@link Query} builder with the given query.
54 * @param query the query to populate the builder
56 private Builder(Query query) {
57 this.queryString = query.getQueryString();
58 this.options = query.getOptions();
61 /**
62 * Sets the query options.
64 * @param options the {@link QueryOptions} to apply to the search results
65 * @return this builder
67 public Builder setOptions(QueryOptions options) {
68 this.options = options;
69 return this;
72 /**
73 * Sets the query options from a builder.
75 * @param optionsBuilder the {@link QueryOptions.Builder} build a
76 * {@link QueryOptions} to apply to the search results
77 * @return this builder
79 public Builder setOptions(QueryOptions.Builder optionsBuilder) {
80 return setOptions(optionsBuilder.build());
83 /**
84 * Sets the query string used to construct the query.
86 * @param query a query string used to construct the query
87 * @return this Builder
88 * @throws SearchQueryException if the query string does not parse
90 protected Builder setQueryString(String query) {
91 this.queryString = QueryChecker.checkQuery(query);
92 return this;
95 /**
96 * Build a {@link Query} from the query string and the parameters set on
97 * the {@link Builder}. A query string can be as simple as a single term
98 * ("foo"), or as complex as a boolean expression, including field names
99 * ("title:hello OR body:important -october").
101 * @param queryString the query string to parse and apply to an index
102 * @return the Query built from the parameters entered on this
103 * Builder including the queryString
104 * @throws SearchQueryException if the query string is invalid
106 public Query build(String queryString) {
107 setQueryString(queryString);
108 return new Query(this);
112 * Construct the message.
114 * @return the Query built from the parameters entered on this
115 * Builder
116 * @throws IllegalArgumentException if the query string is invalid
118 public Query build() {
119 return new Query(this);
123 private final String query;
124 private final QueryOptions options;
127 * Creates a query from the builder.
129 * @param builder the query builder to populate with
131 protected Query(Builder builder) {
132 query = builder.queryString;
133 options = builder.options;
134 checkValid();
138 * The query can be as simple as a single term ("foo"), or as complex
139 * as a boolean expression, including field names ("title:hello OR
140 * body:important -october").
142 * @return the query
144 public String getQueryString() {
145 return query;
149 * @return the {@link QueryOptions} for controlling the what is returned
150 * in the result set matching the query
152 public QueryOptions getOptions() {
153 return options;
157 * Creates and returns a {@link Query} builder. Set the query
158 * parameters and use the {@link Builder#build()} method to create a concrete
159 * instance of Query.
161 * @return a {@link Builder} which can construct a query
163 public static Builder newBuilder() {
164 return new Builder();
168 * Creates a builder from the given query.
170 * @param query the query for the builder to use to build another query
171 * @return a new builder with values based on the given request
173 public static Builder newBuilder(Query query) {
174 return new Builder(query);
178 * Checks the query is valid, specifically, has a non-null
179 * query string.
181 * @return this checked Query
182 * @throws NullPointerException if query is null
184 private Query checkValid() {
185 Preconditions.checkNotNull(query, "query cannot be null");
186 return this;
190 * Copies the contents of this {@link Query} object into a
191 * {@link SearchParams} protocol buffer builder.
193 * @return a search params protocol buffer builder initialized with
194 * the values from this query
195 * @throws IllegalArgumentException if the cursor type is
196 * unknown
198 SearchParams.Builder copyToProtocolBuffer() {
199 SearchParams.Builder builder = SearchParams.newBuilder().setQuery(query);
200 if (options == null) {
201 QueryOptions.newBuilder().build().copyToProtocolBuffer(builder, query);
202 } else {
203 options.copyToProtocolBuffer(builder, query);
205 return builder;
208 @Override
209 public String toString() {
210 return new Util.ToStringHelper("Query")
211 .addField("queryString", query)
212 .addField("options", options)
213 .finish();