/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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.apache.solr.search.concordance; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; import org.apache.lucene.search.concordance.classic.AbstractConcordanceWindowCollector; import org.apache.lucene.search.concordance.classic.ConcordanceWindow; import org.apache.solr.cloud.ZkController; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.SolrCore; import org.apache.solr.handler.RequestHandlerBase; import org.apache.solr.request.SimpleFacets; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.search.DocSet; import org.apache.solr.search.QParser; import org.apache.solr.search.SyntaxError; public abstract class SolrConcordanceBase extends RequestHandlerBase { protected static void setParam(String name, ModifiableSolrParams params, SolrParams parent) { Object o = parent.get(name); if (o != null) params.set(name, o.toString()); } @SuppressWarnings({"rawtypes", "unchecked"}) public static NamedList convertToList(String solrIndexField, AbstractConcordanceWindowCollector collector) { NamedList results = new NamedList(); results.add("hitMax", collector.getHitMax()); results.add("numDocs", collector.getNumDocs()); results.add("totalDocs", collector.getTotalDocs()); //TODO: add this once we get the deduping stuff going... //results.add("totalWindows", concos.getNumTotalWindows()); results.add("numWindows", collector.getNumWindows()); NamedList windows = new NamedList(); //TODO: add back in metadata // Map<DocMetadata, Integer> metaMaps = new HashMap<DocMetadata, Integer>(); List<ConcordanceWindow> concWindows = collector.getSortedWindows(); for (ConcordanceWindow window : concWindows) { NamedList doc = convertToDoc(solrIndexField, window, true); /* DocMetadata metadata = window.getMetadata(); if(metadata != null && metadata.size() > 0) { Integer id = metaMaps.get(metadata); if(id == null) { id = metaMaps.size(); metaMaps.put(metadata, id); } if(id > 0) doc.add("metadataID", id); }*/ windows.add("window", doc); } /* NamedList metas = new NamedList(); for(Entry<DocMetadata, Integer> kv : metaMaps.entrySet()) { NamedList meta = new NamedList(); meta.add("metadataID", kv.getValue()); meta.add("params", convertToList(kv.getKey().getMap()) ); } if(metas != null && metas.size() > 0) results.add("metadata", metas);*/ results.add("windows", windows); return results; } public static String getField(SolrParams params, String fallBackField) { //TODO: figure out what the standard way of doing this String fieldName = params.get(CommonParams.FIELD); if (fieldName == null || fieldName.equalsIgnoreCase("null")) { if (fieldName == null || fieldName.equalsIgnoreCase("null")) { fieldName = params.get(CommonParams.DF); } if (fieldName == null || fieldName.equalsIgnoreCase("null")) { //check field list if not in field fieldName = params.get(CommonParams.FL); //TODO: change when/if request allows for multiple terms if (fieldName != null) { fieldName = fieldName.split(",")[0].trim(); } } } return (fieldName != null) ? fieldName : fallBackField; } protected static String getString(String name, NamedList nl) { Object o = nl.get(name); if (o != null) return o.toString(); return null; } protected static int getInt(String name, NamedList nl) { Object o = nl.get(name); if (o != null) return (int) o; return 0; } protected static long getLong(String name, NamedList nl) { Object o = nl.get(name); if (o != null) return (long) o; return 0; } protected static double getDouble(String name, NamedList nl) { Object o = nl.get(name); if (o != null) return (double) o; return 0; } protected static NamedList getNL(String name, NamedList nl) { Object o = nl.get(name); if (o != null) return (NamedList) o; return null; } //in NamedList....almost protected static NamedList convertToList(Map<String, ?> map) { NamedList list = new NamedList(); for (Entry<String, ?> kv : map.entrySet()) { Object val = kv.getValue(); if (val != null) { if (val instanceof Map) val = convertToList((Map<String, ?>) val); list.add(kv.getKey(), val); } } return list; } public static NamedList convertToDoc(ConcordanceWindow window) { return convertToDoc(null, window, true); } public static NamedList convertToDoc(String solrIndexField, ConcordanceWindow window, boolean bIncludeMetadata) { NamedList doc = new NamedList(); if (bIncludeMetadata && window.getMetadata() != null && window.getMetadata().size() > 0) doc.add("metadata", window.getMetadata()); doc.add("luceneID", window.getUniqueDocID()); /* if(window.getMetadata() != null) { doc.add(solrIndexField, window.getMetadata().get(solrIndexField)); for(Entry<String, String> kv : window.getMetadata().getMap().entrySet()) if(kv.getValue() != null && kv.getValue().trim().length() > 0) doc.add(kv.getKey(), kv.getValue()); } */ doc.add("end", window.getEnd()); //window.getMetadata(); doc.add("post", window.getPost()); doc.add("pre", window.getPre()); doc.add("size", window.getSize()); doc.add("sortKey", window.getSortKey().toString()); doc.add("start", window.getStart()); doc.add("target", window.getTarget()); return doc; } public static boolean isDistributed(SolrQueryRequest req) { SolrParams params = req.getParams(); //TODO: switch to distrib? and flip bool Boolean localQuery = params.getBool("lq"); if (localQuery == null) localQuery = false; boolean isDistrib = (localQuery) ? false : req.getCore().getCoreDescriptor().getCoreContainer().isZooKeeperAware(); return isDistrib; } public static List<String> getShards(SolrQueryRequest req, boolean bIncludeLocal) { ZkController zoo = req.getCore().getCoreDescriptor().getCoreContainer().getZkController(); //TODO: non-replica's Set<String> nodes = zoo.getClusterState().getLiveNodes(); List<String> shards = new ArrayList<String>(nodes.size()); String thisUrl = req.getCore().getCoreDescriptor().getCoreContainer().getZkController().getBaseUrl(); for (String node : nodes) { String shard = node.replace("_", "/"); if (!bIncludeLocal && thisUrl.contains(shard)) continue; shard += "/" + req.getCore().getName(); shards.add(shard); } return shards; } protected static <T extends RequestHandlerBase> String getHandlerName(SolrCore core, String defaultName, Class<T> clz) { //I'd be just as happy stripping this off the url if I could figure out how... SolrRequestHandler handler = core.getRequestHandler(defaultName); if (handler == null) { for (Entry<String, ? extends RequestHandlerBase> kv : core.getRequestHandlers(clz).entrySet()) return kv.getKey(); } else return defaultName; return null; } protected static <T extends RequestHandlerBase> String getHandlerName(SolrQueryRequest req, String defaultName, Class<T> clz) { return getHandlerName(req.getCore(), defaultName, clz); } public static List<Query> parseFilters(SolrQueryRequest req) throws SyntaxError { return parseFilters(null, req); } protected static NamedList doFacetSearch(Query query, SolrParams params, SolrQueryRequest req) throws IOException, SyntaxError { return doFacetSearch(req.getSearcher().getDocSet(query), params, req); } protected static NamedList doFacetSearch(DocSet docSet, SolrParams params, SolrQueryRequest req) throws IOException, SyntaxError { SimpleFacets f = new SimpleFacets(req, docSet, params, null); NamedList counts = f.getFacetFieldCounts(); return counts; } public static List<Query> parseFilters(Query q, SolrQueryRequest req) throws SyntaxError { List<Query> filters = null; filters = new ArrayList<Query>(); if (q != null) filters.add(q); String[] fqs = req.getParams().getParams(CommonParams.FQ); if (fqs != null && fqs.length != 0) { for (String fq : fqs) { if (fq != null && fq.trim().length() != 0) { QParser fqp = QParser.getParser(fq, null, req); filters.add(fqp.getQuery()); } } } return filters; } public static DocSet getDocSet(Query q, SolrQueryRequest req) throws Exception { List<Query> filters = parseFilters(q, req); if (filters != null && filters.size() > 0) return req.getSearcher().getDocSet(filters); return DocSet.EMPTY; } public static Filter getFilterQuery(SolrQueryRequest req) throws Exception { return getFilterQuery(null, req); } public static Filter getFilterQuery(Query q, SolrQueryRequest req) throws Exception { DocSet docs = getDocSet(q, req); if (docs != null && !docs.equals(DocSet.EMPTY)) { return docs.getTopFilter(); } return null; } protected abstract String getHandlerName(SolrQueryRequest req); }