org.elasticsearch.search.query.SortParseElement.java Source code

Java tutorial

Introduction

Here is the source code for org.elasticsearch.search.query.SortParseElement.java

Source

/*
 * Licensed to Elastic Search and Shay Banon under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Elastic Search licenses this
 * file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.elasticsearch.search.query;

import com.google.common.collect.Lists;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.elasticsearch.index.mapper.FieldMappers;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.util.Booleans;
import org.elasticsearch.util.gnu.trove.TObjectIntHashMap;
import org.elasticsearch.util.trove.ExtTObjectIntHasMap;

import java.io.IOException;
import java.util.List;

/**
 * @author kimchy (shay.banon)
 */
public class SortParseElement implements SearchParseElement {

    private final TObjectIntHashMap<String> sortFieldTypesMapper = new ExtTObjectIntHasMap<String>()
            .defaultReturnValue(-1);

    private static final SortField SORT_SCORE = new SortField(null, SortField.SCORE);
    private static final SortField SORT_SCORE_REVERSE = new SortField(null, SortField.SCORE, true);
    private static final SortField SORT_DOC = new SortField(null, SortField.DOC);
    private static final SortField SORT_DOC_REVERSE = new SortField(null, SortField.DOC, true);

    public SortParseElement() {
        sortFieldTypesMapper.put("string", SortField.STRING);
        sortFieldTypesMapper.put("int", SortField.INT);
        sortFieldTypesMapper.put("float", SortField.FLOAT);
        sortFieldTypesMapper.put("long", SortField.LONG);
        sortFieldTypesMapper.put("double", SortField.DOUBLE);
        sortFieldTypesMapper.put("short", SortField.SHORT);
        sortFieldTypesMapper.put("byte", SortField.BYTE);
        sortFieldTypesMapper.put("string_val", SortField.STRING_VAL);
    }

    @Override
    public void parse(JsonParser jp, SearchContext context) throws Exception {
        JsonToken token = jp.getCurrentToken();
        List<SortField> sortFields = Lists.newArrayListWithCapacity(2);
        if (token == JsonToken.START_ARRAY) {
            while ((token = jp.nextToken()) != JsonToken.END_ARRAY) {
                if (token == JsonToken.START_OBJECT) {
                    addCompoundSortField(jp, context, sortFields);
                } else if (token == JsonToken.VALUE_STRING) {
                    addSortField(context, sortFields, jp.getText(), false, -1);
                }
            }
        } else {
            addCompoundSortField(jp, context, sortFields);
        }
        if (!sortFields.isEmpty()) {
            context.sort(new Sort(sortFields.toArray(new SortField[sortFields.size()])));
        }
    }

    private void addCompoundSortField(JsonParser jp, SearchContext context, List<SortField> sortFields)
            throws IOException {
        JsonToken token;
        while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
            if (token == JsonToken.FIELD_NAME) {
                String fieldName = jp.getCurrentName();
                boolean reverse = false;
                String innerJsonName = null;
                int type = -1;
                while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
                    if (token == JsonToken.FIELD_NAME) {
                        innerJsonName = jp.getCurrentName();
                    } else if (token == JsonToken.VALUE_STRING) {
                        if ("type".equals(innerJsonName)) {
                            type = sortFieldTypesMapper.get(jp.getText());
                            if (type == -1) {
                                throw new SearchParseException(context,
                                        "No sort type for [" + jp.getText() + "] with field [" + fieldName + "]");
                            }
                        } else if ("reverse".equals(innerJsonName)) {
                            reverse = Booleans.parseBoolean(jp.getText(), reverse);
                        }
                    } else if (token == JsonToken.VALUE_NUMBER_INT) {
                        if ("reverse".equals(innerJsonName)) {
                            reverse = jp.getIntValue() != 0;
                        }
                    } else if (token == JsonToken.VALUE_TRUE) {
                        if ("reverse".equals(innerJsonName)) {
                            reverse = true;
                        }
                    }
                }
                addSortField(context, sortFields, fieldName, reverse, type);
            }
        }
    }

    private void addSortField(SearchContext context, List<SortField> sortFields, String fieldName, boolean reverse,
            int type) {
        if ("score".equals(fieldName)) {
            if (reverse) {
                sortFields.add(SORT_SCORE_REVERSE);
            } else {
                sortFields.add(SORT_SCORE);
            }
        } else if ("doc".equals(fieldName)) {
            if (reverse) {
                sortFields.add(SORT_DOC_REVERSE);
            } else {
                sortFields.add(SORT_DOC);
            }
        } else {
            FieldMappers fieldMappers = context.mapperService().smartNameFieldMappers(fieldName);
            if (fieldMappers == null || fieldMappers.mappers().isEmpty()) {
                if (type == -1) {
                    throw new SearchParseException(context,
                            "No built in mapping found for [" + fieldName + "], and no explicit type defined");
                }
            } else {
                fieldName = fieldMappers.mappers().get(0).names().indexName();
                if (type == -1) {
                    type = fieldMappers.mappers().get(0).sortType();
                }
            }
            sortFields.add(new SortField(fieldName, type, reverse));
        }
    }
}