1 // Copyright 2010 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.api
.search
;
5 import com
.google
.appengine
.api
.search
.checkers
.FieldChecker
;
6 import com
.google
.appengine
.api
.search
.checkers
.Preconditions
;
7 import com
.google
.apphosting
.api
.search
.DocumentPb
;
9 import java
.io
.Serializable
;
10 import java
.util
.ArrayList
;
11 import java
.util
.Collections
;
12 import java
.util
.List
;
15 * Represents a document which may have been scored, possibly
16 * some computed expression fields, and a cursor to continue
19 public final class ScoredDocument
extends Document
implements Serializable
{
21 private static final long serialVersionUID
= 3062767930105951671L;
24 * A builder of scored documents. This is not thread-safe.
26 public static final class Builder
extends Document
.Builder
{
27 private final List
<Double
> scores
= new ArrayList
<Double
>();
28 private final List
<Field
> expressions
= new ArrayList
<Field
>();
29 private Cursor cursor
;
32 * Constructs a builder for a scored document.
38 * Sets the cursor to the next set of results from search.
40 * @param cursor the {@link Cursor} for the next set of results
42 * @return this builder
44 public Builder
setCursor(Cursor cursor
) {
50 * Adds the score to the builder.
52 * @param score the score to add
53 * @return this builder
55 public Builder
addScore(double score
) {
61 * Adds the expression to the builder.
63 * @param expression the expression field to add
64 * @return this builder
65 * @throws IllegalArgumentException if the expression field is invalid
67 public Builder
addExpression(Field expression
) {
68 Preconditions
.checkNotNull(expression
, "expression cannot be null");
69 expressions
.add(expression
);
74 * Builds a valid document. The builder must have set a valid document
75 * id, and have a non-empty set of valid fields.
77 * @return the scored document built by this builder
78 * @throws IllegalArgumentException if the scored document built is
82 public ScoredDocument
build() {
83 return new ScoredDocument(this);
87 private final List
<Double
> scores
;
88 private final List
<Field
> expressions
;
89 private final Cursor cursor
;
92 * Constructs a scored document with the given builder.
94 * @param builder the builder capable of building a document
96 private ScoredDocument(Builder builder
) {
98 scores
= Collections
.unmodifiableList(builder
.scores
);
99 expressions
= Collections
.unmodifiableList(builder
.expressions
);
100 cursor
= builder
.cursor
;
104 * The list of scores assigned during sort evaluation. Each sort
105 * dimension is included in this list. Positive scores are used
106 * for ascending sorts; negative scores are used for descending.
108 * @return the list of scores assigned during sort evaluation
110 public List
<Double
> getSortScores() {
115 * The list of Field which are the result of any extra expressions
116 * requested. For example, if a request contains fields to snippet or
117 * {@link FieldExpression FieldExpressions} which are named snippet
118 * expressions, then the returned expression will be a Field with the
119 * name specified in the request and HTML value set to the snippet.
121 * @return the list of Field which are the result of extra expressions
124 public List
<Field
> getExpressions() {
129 * A {@link Cursor} to be used continuing search after this search
130 * result. For this field to be populated, use
131 * {@link QueryOptions.Builder#setCursor(Cursor)}, where the cursor is
132 * created by {@code Cursor.newBuilder().setPerResult(true).build()}.
133 * Otherwise {@link #getCursor} will return null.
135 * @return a cursor used for issuing a subsequent search that
136 * will return elements beginning after this result. Can be null
138 public Cursor
getCursor() {
142 public static ScoredDocument
.Builder
newBuilder() {
143 return new ScoredDocument
.Builder();
147 * Creates a new scored document builder from the given document. All
148 * document properties are copied to the returned builder.
150 * @param document the document protocol buffer to build a scored document
152 * @return the scored document builder initialized from a document protocol
154 * @throws SearchException if a field value is invalid
156 static ScoredDocument
.Builder
newBuilder(DocumentPb
.Document document
) {
157 ScoredDocument
.Builder docBuilder
= ScoredDocument
.newBuilder();
158 docBuilder
.setId(document
.getId());
159 if (document
.hasLanguage()) {
160 docBuilder
.setLocale(FieldChecker
.parseLocale(document
.getLanguage()));
162 for (DocumentPb
.Field field
: document
.getFieldList()) {
163 docBuilder
.addField(Field
.newBuilder(field
));
165 if (document
.hasOrderId()) {
166 docBuilder
.setRank(document
.getOrderId());
172 public String
toString() {
173 return new Util
.ToStringHelper("ScoredDocument")
174 .addField("documentId", getId())
175 .addIterableField("fields", getFields(), MAX_FIELDS_TO_STRING
)
176 .addField("locale", getLocale())
177 .addField("rank", getRank())
178 .addIterableField("scores", scores
)
179 .addIterableField("expressions", expressions
)
180 .addField("cursor", cursor
)