
com.dell.doradus.olap.search.SearchResultBuilder Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2014 Dell, Inc.
*
* Licensed 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 com.dell.doradus.olap.search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.dell.doradus.common.FieldDefinition;
import com.dell.doradus.common.FieldType;
import com.dell.doradus.olap.store.CubeSearcher;
import com.dell.doradus.olap.store.FieldSearcher;
import com.dell.doradus.olap.store.IdSearcher;
import com.dell.doradus.olap.store.IntIterator;
import com.dell.doradus.olap.store.NumSearcherMV;
import com.dell.doradus.olap.store.ValueSearcher;
import com.dell.doradus.search.FieldSet;
import com.dell.doradus.search.SearchResult;
import com.dell.doradus.search.SearchResultList;
import com.dell.doradus.search.aggregate.SortOrder;
public class SearchResultBuilder {
public static SearchResultList build(CubeSearcher searcher, Result documents, FieldSet fieldSet, int size, SortOrder[] orders) {
if(documents.countSet() == 0) {
SearchResultList empty = new SearchResultList();
empty.documentsCount = 0;
return empty;
}
if(size == 0) size = Integer.MAX_VALUE;
fieldSet.limit = size;
FieldSetCreator fieldSetCreator = new FieldSetCreator(searcher, fieldSet, orders);
FVS fvs = new FVS();
IntIterator documents_iter = SearchResultComparer.sort(searcher, documents, orders, size);
IntIterator iter = new IntIterator();
fill(searcher, documents_iter, fvs, fieldSetCreator, iter);
fvs.resolve(searcher);
SearchResultList list = new SearchResultList();
list.documentsCount = documents.countSet();
for(int doc = 0; doc < documents_iter.count(); doc++) {
int d = documents_iter.get(doc);
SearchResult child = build(searcher, d, fvs, fieldSetCreator, iter);
child.orders = orders;
list.results.add(child);
}
Collections.sort(list.results);
if(list.results.size() > size) {
List subList = list.results.subList(0, size);
list.results = new ArrayList(subList);
}
if(list.results.size() >= size && list.results.size() > 0) {
list.continuation_token = list.results.get(list.results.size() - 1).id();
}
return list;
}
private static void fill(CubeSearcher searcher, IntIterator documents, FVS fvs, FieldSetCreator fieldSetCreator, IntIterator iter) {
String table = fieldSetCreator.tableDef.getTableName();
fvs.add(table, "_ID", fieldSetCreator.filter, documents, fieldSetCreator.limit);
for(String field : fieldSetCreator.scalarFields) {
FieldDefinition fieldDef = fieldSetCreator.tableDef.getFieldDef(field);
if(fieldDef == null) throw new IllegalArgumentException("Unknown field: " + field);
FieldType type = fieldDef.getType();
if(type == FieldType.TEXT || type == FieldType.BINARY) {
FieldSearcher field_searcher = searcher.getFieldSearcher(table, field);
int num = 0;
for(int doc = 0; doc < documents.count(); doc++) {
if(num >= fieldSetCreator.limit) break;
int d = documents.get(doc);
if(fieldSetCreator.filter != null && !fieldSetCreator.filter.get(d)) continue;
field_searcher.fields(d, iter);
fvs.add(table, field, null, iter, Integer.MAX_VALUE);
num++;
}
}
}
for(Map.Entry> e : fieldSetCreator.links.entrySet()) {
String link = e.getKey();
List linkedSetList = e.getValue();
for(FieldSetCreator linkedSet: linkedSetList) {
FieldSearcher field_searcher = searcher.getFieldSearcher(table, link);
IntIterator iter2 = new IntIterator();
int num = 0;
for(int doc = 0; doc < documents.count(); doc++) {
if(num >= fieldSetCreator.limit) break;
int d = documents.get(doc);
if(fieldSetCreator.filter != null && !fieldSetCreator.filter.get(d)) continue;
field_searcher.fields(d, iter);
fill(searcher, iter, fvs, linkedSet, iter2);
num++;
}
}
}
}
private static SearchResult build(CubeSearcher searcher, int document, FVS fvs, FieldSetCreator fieldSetCreator, IntIterator iter) {
SearchResult sr = new SearchResult();
sr.fieldSet = fieldSetCreator.fieldSet;
String table = fieldSetCreator.tableDef.getTableName();
sr.scalars.put("_ID", fvs.get(table, "_ID", document));
for(String field : fieldSetCreator.scalarFields) {
FieldDefinition fieldDef = fieldSetCreator.tableDef.getFieldDef(field);
if(fieldDef == null) throw new IllegalArgumentException("Unknown field: " + field);
FieldType type = fieldDef.getType();
if(type == FieldType.TEXT || type == FieldType.BINARY) {
FieldSearcher field_searcher = searcher.getFieldSearcher(table, field);
field_searcher.fields(document, iter);
if(iter.count() == 0) continue;
String value = "";
for(int i = 0; i < iter.count(); i++) {
if(value.length() > 0) value += "\uFFFE";
value += fvs.get(table, field, iter.get(i));
}
sr.scalars.put(field, value);
} else if(NumSearcherMV.isNumericType(type)) {
NumSearcherMV num_searcher = searcher.getNumSearcher(table, field);
if(num_searcher.isNull(document)) continue;
String value = "";
int size = num_searcher.size(document);
if(size == 0) continue;
for(int i = 0; i < size; i++) {
if(value.length() > 0) value += "\uFFFE";
value += NumSearcherMV.format(num_searcher.get(document, i), type);
}
sr.scalars.put(field, value);
} else throw new IllegalArgumentException("Invalid type: " + type + " for field " + field);
}
for(Map.Entry> e : fieldSetCreator.links.entrySet()) {
String link = e.getKey();
List linkedSetList = e.getValue();
List childrenList = new ArrayList();
sr.links.put(link, childrenList);
for(FieldSetCreator linkedSet: linkedSetList) {
FieldSearcher field_searcher = searcher.getFieldSearcher(table, link);
IntIterator iter2 = new IntIterator();
field_searcher.fields(document, iter);
SearchResultList childList = new SearchResultList();
int num = 0;
for(int doc = 0; doc < iter.count(); doc++) {
if(num >= linkedSet.limit) break;
int d = iter.get(doc);
if(linkedSet.filter != null && !linkedSet.filter.get(d)) continue;
SearchResult child = build(searcher, iter.get(doc), fvs, linkedSet, iter2);
childList.results.add(child);
num++;
}
childrenList.add(childList);
}
}
return sr;
}
static class FVS {
public Map fvs = new HashMap();
public String get(String table, String field, int term) {
return fvs.get(table + "." + field).get(term);
}
public void add(String table, String field, Result filter, IntIterator terms, int size) {
String key = table + "." + field;
FV fv = fvs.get(key);
if(fv == null) {
fv = new FV(table, field);
fvs.put(key, fv);
}
int num = 0;
if(size < 0) size = Integer.MAX_VALUE;
for(int i = 0; i < terms.count(); i++) {
if(num >= size) break;
int t = terms.get(i);
if(filter != null && !filter.get(t)) continue;
fv.add(t);
num++;
}
}
public void resolve(CubeSearcher searcher) {
for(FV fv : fvs.values()) fv.resolve(searcher);
}
}
static class FV {
public String table;
public String field;
public Map values = new HashMap();
public FV(String table, String field) {
this.table = table;
this.field = field;
}
public void add(int i) { values.put(i, null); }
public String get(int i) {
String val = values.get(i);
return val;
}
public void resolve(CubeSearcher searcher) {
if(field == "_ID") {
IdSearcher id_searcher = searcher.getIdSearcher(table);
List li = new ArrayList();
li.addAll(values.keySet());
Collections.sort(li);
for(int i : li) {
values.put(i, id_searcher.getId(i).toString());
}
} else {
ValueSearcher value_searcher = searcher.getValueSearcher(table, field);
List li = new ArrayList();
li.addAll(values.keySet());
Collections.sort(li);
for(int i : li) {
values.put(i, value_searcher.getValue(i).toString());
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy