001/* 002 * (C) Copyright 2014-2015 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Benoit Delbosc 018 * Florent Guillaume 019 */ 020package org.nuxeo.elasticsearch.core; 021 022import java.io.Serializable; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Map; 026import java.util.NoSuchElementException; 027 028import org.elasticsearch.action.search.SearchResponse; 029import org.nuxeo.ecm.core.api.IterableQueryResult; 030import org.nuxeo.ecm.core.schema.types.Type; 031 032/** 033 * Iterable query result of the results of an Elasticsearch query. 034 * <p> 035 * Loads all results in memory. 036 * 037 * @since 7.2 038 */ 039public class EsResultSetImpl implements IterableQueryResult, Iterator<Map<String, Serializable>> { 040 041 private final SearchResponse response; 042 043 private final Map<String, Type> selectFieldsAndTypes; 044 045 boolean closed; 046 047 protected List<Map<String, Serializable>> maps; 048 049 protected long size; 050 051 private long pos; 052 053 public EsResultSetImpl(SearchResponse response, Map<String, Type> selectFieldsAndTypes) { 054 this.response = response; 055 this.selectFieldsAndTypes = selectFieldsAndTypes; 056 maps = buildMaps(); 057 size = maps.size(); 058 } 059 060 protected List<Map<String, Serializable>> buildMaps() { 061 return new EsSearchHitConverter(selectFieldsAndTypes).convert(response.getHits().getHits()); 062 } 063 064 @Override 065 public void close() { 066 closed = true; 067 pos = -1; 068 } 069 070 @Override 071 public boolean isLife() { 072 return !closed; 073 } 074 075 @Override 076 public boolean mustBeClosed() { 077 return false; // holds no resources 078 } 079 080 @Override 081 public long size() { 082 return response.getHits().getTotalHits(); 083 } 084 085 @Override 086 public long pos() { 087 return pos; 088 } 089 090 @Override 091 public void skipTo(long pos) { 092 if (pos < 0) { 093 pos = 0; 094 } else if (pos > size) { 095 pos = size; 096 } 097 this.pos = pos; 098 } 099 100 @Override 101 public Iterator<Map<String, Serializable>> iterator() { 102 return this; 103 } 104 105 @Override 106 public boolean hasNext() { 107 return pos < size; 108 } 109 110 @Override 111 public Map<String, Serializable> next() { 112 if (closed || pos == size) { 113 throw new NoSuchElementException(); 114 } 115 Map<String, Serializable> map = maps.get((int) pos); 116 pos++; 117 return map; 118 } 119 120}