/* * Copyright 2010 Bizosys Technologies Limited * * Licensed to the Bizosys Technologies Limited (Bizosys) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The Bizosys 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 com.bizosys.hsearch.query; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.bizosys.hsearch.common.ByteField; import com.bizosys.hsearch.common.WhoAmI; import com.bizosys.hsearch.common.Account.AccountInfo; import com.bizosys.hsearch.filter.Storable; import com.bizosys.hsearch.util.GeoId; import com.bizosys.oneline.ApplicationFault; import com.bizosys.oneline.util.StringUtils; public class QueryContext { private static final boolean DEBUG_ENABLED = QueryLog.l.isDebugEnabled(); /** * The ip address of the searcher */ public String ipAddress = null; /** * The user who is accessing it. */ public WhoAmI user = null; /* ************************************************ * The filteration criteria applied to search ***** * ***********************************************/ /** * Query term as it is.. */ public String queryString = null; /** * Search in Tags */ public boolean matchTags = false; /** * Scroll till (This is a number based on the page */ public int scroll = 0; /** * The document type which needs to be scanned * Table Name / File Extension / Dna Name */ public String docType = null; /** * The document type which needs to be scanned * Table Name / File Extension / Dna Name */ public Byte docTypeCode = null; /** * The state of the docucment (Applied, Processed) */ public Storable state = null; /** * Just the department (HR, PRODUCTION) */ public Storable team = null; /** * Original Document Creation time */ public Long createdAfter = null; public Long createdBefore = null; /** * Document modification time */ public Long modifiedAfter = null; public Long modifiedBefore = null; /** * Area proximity where things will be looked into. */ public int areaInKmRadius = -1; /** * Look documents created from this IP only */ public String matchIp = null; /** * The latitude, longitude */ private GeoId geoId = null; /* ************************************************ * How to Rank ***** * ***********************************************/ public int boostMultiPhrase = 1; //term as well as doc public int boostTermWeight = 1; //term as well as doc public int boostDocumentWeight = 1; //term as well as doc public int boostIpProximity = 1; public int boostOwner = 1; public int boostFreshness = 1; public int boostPrecious = 1; public int boostChoices = 1; /* ************************************************ * How much to retrieve ***** * ***********************************************/ public int teaserSectionLen = -1; //Complete Document public int facetFetchLimit = 1000; public int metaFetchLimit = -1; public int documentFetchLimit = -1; public String[] metaFields = null; public Map<String, String> sortOnMeta = null; //orgUnit:asc public Map<String, String> sortOnFld = null; //empName:asc public static String SORT_ASC = "asc"; public static String SORT_DESC = "desc"; public Set<String> clusters = null; //nlp,orgunit,id,abc public boolean isTouchStone = false; public int totalTerms = 0; /** * Hints */ public boolean isOrgUnit = false; public boolean isDocType = false; private String tenant = null; private List<byte[]> buckets = null; //Restricted to the given buckets /** * Initializes the query context for the given tenant scope * @param tenant * @param queryString * @throws ApplicationFault */ public QueryContext(AccountInfo account, String queryString) throws ApplicationFault { if ( null == account)throw new ApplicationFault("No Account Information"); if ( StringUtils.isEmpty(queryString) ) throw new ApplicationFault("Null query"); this.queryString = queryString.toLowerCase(); this.tenant = account.name; this.buckets = account.buckets; int bucketsT = (null == this.buckets ) ? 0 : this.buckets.size(); if ( 0 == bucketsT ) { String errMsg = "No buckets allocated."; throw new ApplicationFault(errMsg); } else { if ( DEBUG_ENABLED) { String msg = "Total Buckets Found" + bucketsT + "="; for (byte[] bucket : this.buckets) { msg = msg + " " + ByteField.getLong(0, bucket); } QueryLog.l.debug(msg); } } } public String getTenant() { return this.tenant; } public List<byte[]> getBuckets() { return this.buckets; } /** public void setGeoId(GeoId geoId){ this.geoId = geoId; } public GeoId getGeoId() throws ApplicationFault, SystemFault { if ( null != geoId) return geoId; if ( null == this.ipAddress || "0.0.0.0".equals(this.ipAddress) || "127.0.0.1".equals(this.ipAddress) || "localhost".equals(this.ipAddress)) { return null; } int ip = IpUtil.computeHouse(this.ipAddress); Location loc = null; try { loc = new GeoService().getLocation(ip); } catch (Exception ex) { QueryLog.l.fatal("outflow.QueryContext GeoService Invocation Failure", ex); throw new SystemFault(ex); } if ( null == loc) return null; geoId = GeoId.convertLatLng(loc.latitude, loc.longitude); return geoId; } */ /** * This populates the query Context element from the * Lucene Style Query String * @param reserveWord * @param value */ public void populate (int reserveWord, String value) throws ApplicationFault { if ( StringUtils.isEmpty(value)) return; value = value.replace('_', ' ').trim(); if ( DEBUG_ENABLED) QueryLog.l.debug( "QueryContext> Value=" + value + " ,reserve sequence " + reserveWord); switch (reserveWord) { case ReserveQueryWord.RESERVE_docType: this.docType = value; break; case ReserveQueryWord.RESERVE_scroll: this.scroll = new Integer(value); if ( this.scroll < 0 ) this.scroll = 0; break; case ReserveQueryWord.RESERVE_state: this.state = new Storable(value); break; case ReserveQueryWord.RESERVE_team: this.team = new Storable(value); break; case ReserveQueryWord.RESERVE_createdBefore: this.createdBefore = Long.parseLong(value); break; case ReserveQueryWord.RESERVE_createdAfter: this.createdAfter = Long.parseLong(value); break; case ReserveQueryWord.RESERVE_modifiedAfter: this.modifiedAfter = Long.parseLong(value); break; case ReserveQueryWord.RESERVE_modifiedBefore: this.modifiedBefore = Long.parseLong(value); break; case ReserveQueryWord.RESERVE_areaInKmRadius: this.areaInKmRadius = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_matchIp: this.matchIp = value; break; case ReserveQueryWord.RESERVE_latlng: String[] latlng = StringUtils.getStrings(value, ','); if ( null == geoId) this.geoId = GeoId.convertLatLng( Float.parseFloat(latlng[0]), Float.parseFloat(latlng[1])); break; case ReserveQueryWord.RESERVE_boostMultiphrase: this.boostMultiPhrase = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostTermWeight: this.boostTermWeight = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostDocumentWeight: this.boostDocumentWeight = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostIpProximity: this.boostIpProximity = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostOwner: this.boostOwner = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostFreshness: this.boostFreshness = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostPrecious: this.boostPrecious = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_boostChoices: this.boostChoices = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_facetFetchLimit: this.facetFetchLimit = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_metaFetchLimit: this.metaFetchLimit = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_documentFetchLimit: this.documentFetchLimit = Integer.parseInt(value); if ( this.metaFetchLimit < this.documentFetchLimit) this.metaFetchLimit = this.documentFetchLimit; break; case ReserveQueryWord.RESERVE_teaserSectionLength: this.teaserSectionLen = Integer.parseInt(value); break; case ReserveQueryWord.RESERVE_metaFields: this.metaFields = StringUtils.getStrings(value, ","); break; case ReserveQueryWord.RESERVE_cluster: if ( null == clusters) clusters = new HashSet<String>(); List<String> lstClusters = StringUtils.fastSplit(value, ','); for (String cl : lstClusters) { clusters.add(cl); } break; case ReserveQueryWord.RESERVE_sortOnMeta: if ( null == sortOnMeta) sortOnMeta = new HashMap<String, String>(); String[] sortValues = StringUtils.getStrings(value, '='); switch (sortValues.length) { case 1: this.sortOnMeta.put(sortValues[0], SORT_ASC); break; case 2: validateSortingStyle(sortValues[1]); this.sortOnMeta.put(sortValues[0],sortValues[1]); break; default: throw new ApplicationFault("Parsing Failure : Invalid sorting. Ex id=asc"); } break; case ReserveQueryWord.RESERVE_touchstones: this.isTouchStone = true; break; case ReserveQueryWord.RESERVE_sortOnField: if ( null == sortOnFld) sortOnFld = new HashMap<String, String>(); String[] sortFldValues = StringUtils.getStrings(value, '='); switch (sortFldValues.length) { case 1: this.sortOnFld.put(sortFldValues[0], SORT_ASC); break; case 2: validateSortingStyle(sortFldValues[1]); this.sortOnFld.put(sortFldValues[0],sortFldValues[1]); break; default: throw new ApplicationFault("Parsing Failure : Invalid sorting. Ex empname=asc"); } break; } } /** * Needs to be either asc or desc * @param sortType * @throws ApplicationFault */ private void validateSortingStyle(String sortType) throws ApplicationFault { boolean isProperSorting = SORT_ASC.equals(sortType) || SORT_DESC.equals(sortType) ; if ( !isProperSorting) { throw new ApplicationFault("Parsing Failure : Invalid sorting option. Ex " + SORT_ASC + " or " + SORT_DESC ); } } @Override public String toString() { StringBuilder sb = new StringBuilder(); if ( null != ipAddress ) sb.append("ipAddress =").append(ipAddress ).append('\n'); if ( null != user ) sb.append("user =").append(user.toString() ).append('\n'); if ( null != queryString ) sb.append("queryString =").append(queryString).append('\n'); if ( null != docType ) sb.append("docType =").append(docType).append('\n'); if ( null != state ) sb.append("state =").append(state.getValue() ).append('\n'); if ( null != team ) sb.append("orgUnit =").append(team.getValue() ).append('\n'); if ( null != createdBefore ) sb.append("bornBefore =").append(new Date(createdBefore).toString() ).append('\n'); if ( null != createdAfter ) sb.append("bornAfter =").append(new Date(createdAfter ).toString() ).append('\n'); if ( null != modifiedAfter ) sb.append("touchAfter =").append(new Date(modifiedAfter ).toString() ).append('\n'); if ( null != modifiedBefore ) sb.append("touchBefore =").append(new Date(modifiedBefore ).toString() ).append('\n'); if ( -1 != areaInKmRadius ) sb.append("areaInKmRadius =").append(areaInKmRadius).append('\n'); if ( null != matchIp ) sb.append("matchIp =").append(matchIp ).append('\n'); if ( null != geoId ) sb.append("geoId =").append(geoId.toString() ).append('\n'); if ( 1 != boostDocumentWeight ) sb.append("docBoost =").append(boostDocumentWeight ).append('\n'); if ( 1 != boostIpProximity ) sb.append("networkBoost =").append(boostIpProximity ).append('\n'); if ( 1 != boostOwner ) sb.append("authorBoost =").append(boostOwner ).append('\n'); if ( 1 != boostFreshness ) sb.append("freshnessBoost =").append(boostFreshness ).append('\n'); if ( 1 != boostPrecious ) sb.append("preciousBoost =").append(boostPrecious ).append('\n'); if ( 1 != boostChoices ) sb.append("choiceBoost =").append(boostChoices ).append('\n'); sb.append("facetFetchLimit =").append(facetFetchLimit ).append('\n'); sb.append("metaFetchLimit =").append(metaFetchLimit ).append('\n'); sb.append("documentFetchLimit =").append(documentFetchLimit ).append('\n'); if ( -1 != teaserSectionLen) sb.append("teaserSectionLen =").append(teaserSectionLen).append('\n'); if ( null != clusters) sb.append("cluster =").append(clusters).append('\n'); if ( null != sortOnMeta) sb.append("sortOnMeta =").append(sortOnMeta).append('\n'); if ( null != sortOnFld) sb.append("sortOnFld =").append(sortOnFld).append('\n'); if ( null != this.metaFields) { for (String metaFld: this.metaFields) { sb.append("Asked Meta =").append(metaFld).append('\n'); } } return sb.toString(); } }