/** * This software is licensed to you under the Apache License, Version 2.0 (the * "Apache License"). * * LinkedIn's contributions are made under the Apache License. If you contribute * to the Software, the contributions will be deemed to have been made under the * Apache License, unless you expressly indicate otherwise. Please do not make any * contributions that would be inconsistent with the Apache License. * * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, this software * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache * License for the specific language governing permissions and limitations for the * software governed under the Apache License. * * © 2012 LinkedIn Corp. All Rights Reserved. */ package com.senseidb.search.client.req.query; import com.senseidb.search.client.json.CustomJsonHandler; import com.senseidb.search.client.req.Operator; /** * <p> * A family of <code>text</code> queries that accept text, analyzes it, and * constructs a query out of it. For example: * </p> * * <pre class="prettyprint lang-js"> * <span class="pun">{</span><span class="pln"><br>    </span><span class="str">"text"</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"><br>        </span><span class="str">"message"</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="str">"this is a test"</span><span class="pln"><br>    </span><span class="pun">}</span><span class="pln"><br></span><span class="pun">}</span> * </pre> * * <p> * Note, even though the name is text, it also supports exact matching ( * <code>term</code> like) on numeric values and dates. * </p> * <p> * Note, <code>message</code> is the name of a field, you can subsitute the name * of any field (including <code>_all</code>) instead. * </p> * <h2>Types of Text Queries</h2> <h3>boolean</h3> * <p> * The default <code>text</code> query is of type <code>boolean</code>. It means * that the text provided is analyzed and the analysis process constructs a * boolean query from the provided text. The <code>operator</code> flag can be * set to <code>or</code> or <code>and</code> to control the boolean clauses * (defaults to <code>or</code>). * </p> * * <p> * The <code>analyzer</code> can be set to control which analyzer will perform * the analysis process on the text. It default to the field explicit mapping * definition, or the default search analyzer. * </p> * <p> * <code>fuzziness</code> can be set to a value (depending on the relevant type, * for string types it should be a value between <code>0.0</code> and * <code>1.0</code>) to constructs fuzzy queries for each term analyzed. The * <code>prefix_length</code> and <code>max_expansions</code> can be set in this * case to control the fuzzy process. * </p> * * <p> * Here is an example when providing additional parameters (note the slight * change in structure, <code>message</code> is the field name): * </p> * * <h3>phrase</h3> * <p> * The <code>text_phrase</code> query analyzes the text and creates a * <code>phrase</code> query out of the analyzed text. For example: * </p> * <p> * Since <code>text_phrase</code> is only a <code>type</code> of a * <code>text</code> query, it can also be used in the following manner: * </p> * * <p> * A phrase query maintains order of the terms up to a configurable * <code>slop</code> (which defaults to 0). * </p> * <p> * The <code>analyzer</code> can be set to control which analyzer will perform * the analysis process on the text. It default to the field explicit mapping * definition, or the default search analyzer, for example: * </p> * * <h3>text_phrase_prefix</h3> * <p> * The <code>text_phrase_prefix</code> is the same as <code>text_phrase</code>, * expect it allows for prefix matches on the last term in the text. For * example: * </p> * <p> * Or: * </p> * <p> * It accepts the same parameters as the phrase type. In addition, it also * accepts a <code>max_expansions</code> parameter that can control to how many * prefixes the last term will be expanded. It is highly recommended to set it * to an acceptable value to control the execution time of the query. For * example: * </p> * <h2>Comparison to query_string / field</h2> * <p> * The text family of queries does not go through a “query parsing” process. It * does not support field name prefixes, wildcard characters, or other “advance” * features. For this reason, chances of it failing are very small / non * existent, and it provides an excellent behavior when it comes to just analyze * and run that text as a query behavior (which is usually what a text search * box does). Also, the <code>phrase_prefix</code> can provide a great “as you * type” behavior to automatically load search results. * </p> */ @CustomJsonHandler(value = QueryJsonHandler.class) public class TextQuery extends FieldAwareQuery { private String value; private Operator operator; private Type type; private double boost; public TextQuery(String field, String value, Operator operator, Type type, double boost) { super(); this.field = field; this.value = value; this.operator = operator; this.type = type; this.boost = boost; } public static enum Type { phrase_prefix, phrase; } @Override public String getField() { return field; } public String getValue() { return value; } public Operator getOperator() { return operator; } public Type getType() { return type; } public double getBoost() { return boost; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(operator == null ? "" : operator.toString()); builder.append(" ").append(super.toString()); // for field builder.append(" ").append(value == null ? "" : value); builder.append(" ").append(type == null ? "" : type.toString()); builder.append("^").append(boost); return builder.toString(); } }