Author: bpoussin Date: 2012-05-31 17:11:50 +0200 (Thu, 31 May 2012) New Revision: 1478 Url: http://nuiton.org/repositories/revision/wikitty/1478 Log: Evolution #2121: add new query property wikittyFieldSearchDepth on query that permit to follow link between wikitty for search Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java 2012-05-31 15:03:05 UTC (rev 1477) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQuery.java 2012-05-31 15:11:50 UTC (rev 1478) @@ -101,6 +101,11 @@ /** Sort descending on fields. */ protected List<Element> sortDescending; + /** Profondeur de recherche sur les champs de type wikitty. Ce qui permet + de ne pas passer un id ou faire un select, mais directement passer une chaine. + Par defaut pas de recherche profonde, une valeur superieur a 1 est + dangereuse pour les performances. */ + protected int wikittyFieldSearchDepth = 0; /** create anonymous query */ public WikittyQuery() { @@ -143,7 +148,8 @@ ObjectUtils.equals(this.getFacetSort(), other.getFacetSort()) && ObjectUtils.equals(this.getFacetMinCount(), other.getFacetMinCount()) && ObjectUtils.equals(this.getFacetQuery(), other.getFacetQuery()) && - ObjectUtils.equals(this.getCondition(), other.getCondition()); + ObjectUtils.equals(this.getCondition(), other.getCondition()) && + ObjectUtils.equals(this.getWikittyFieldSearchDepth(), other.getWikittyFieldSearchDepth()); } else { result = false; } @@ -402,4 +408,13 @@ return this; } + public int getWikittyFieldSearchDepth() { + return wikittyFieldSearchDepth; + } + + public WikittyQuery setWikittyFieldSearchDepth(int wikittyFieldSearchDepth) { + this.wikittyFieldSearchDepth = wikittyFieldSearchDepth; + return this; + } + } Modified: trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java =================================================================== --- trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2012-05-31 15:03:05 UTC (rev 1477) +++ trunk/wikitty-api/src/main/java/org/nuiton/wikitty/query/WikittyQueryVisitorCopy.java 2012-05-31 15:11:50 UTC (rev 1478) @@ -99,6 +99,7 @@ q.setName(o.getName()); q.setSortAscending(new ArrayList<Element>(o.getSortAscending())); q.setSortDescending(new ArrayList<Element>(o.getSortDescending())); + q.setWikittyFieldSearchDepth(o.getWikittyFieldSearchDepth()); for (FacetQuery c : o.getFacetQuery()) { WikittyQueryVisitorCopy v = new WikittyQueryVisitorCopy(); Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java =================================================================== --- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2012-05-31 15:03:05 UTC (rev 1477) +++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/SolrUtil.java 2012-05-31 15:11:50 UTC (rev 1478) @@ -24,6 +24,11 @@ */ package org.nuiton.wikitty.storage.solr; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.solr.client.solrj.SolrQuery; @@ -33,36 +38,11 @@ import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; -import org.nuiton.wikitty.WikittyException; -import org.nuiton.wikitty.entities.WikittyTypes; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; import org.nuiton.util.TimeLog; -import org.nuiton.wikitty.entities.FieldType; +import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.entities.WikittyTreeNode; import org.nuiton.wikitty.entities.WikittyTypes; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SOLR_ID; -// FIXME REMOVE IT if search on multivalued work with new hack (specific sortable field -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_BINARY_MULTIVALUED; -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_BOOLEAN_MULTIVALUED; -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_DATE_MULTIVALUED; -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_NUMERIC_MULTIVALUED; -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_STRING_MULTIVALUED; -//import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_WIKITTY_MULTIVALUED; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.TREENODE_PARENTS; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.TREENODE_ATTACHED; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_BINARY; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_BOOLEAN; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_DATE; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_NUMERIC; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_STRING; -import static org.nuiton.wikitty.storage.solr.WikittySolrConstant.SUFFIX_WIKITTY; - /** * * @author poussin @@ -71,7 +51,7 @@ * Last update: $Date$ * by : $Author$ */ -public class SolrUtil { +public class SolrUtil implements WikittySolrConstant { /** to use log facility, just put in your code: log.info(\"...\"); */ final static private Log log = LogFactory.getLog(SolrUtil.class); @@ -227,6 +207,10 @@ long numfound = result.getResults().getNumFound(); timeLog.log(start, "executeQuery", String.format( "nb result %s/%s query was '%s'", numGet, numfound, query)); + if (log.isDebugEnabled()) { + log.debug(String.format( + "nb result %s/%s query was '%s'", numGet, numfound, query)); + } return result; } Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java =================================================================== --- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java 2012-05-31 15:03:05 UTC (rev 1477) +++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittyQueryVisitorToSolr.java 2012-05-31 15:11:50 UTC (rev 1478) @@ -25,11 +25,18 @@ package org.nuiton.wikitty.storage.solr; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; import org.nuiton.wikitty.WikittyException; import org.nuiton.wikitty.query.WikittyQuery; import org.nuiton.wikitty.query.WikittyQueryResult; @@ -42,6 +49,7 @@ import org.nuiton.wikitty.query.conditions.ContainsAll; import org.nuiton.wikitty.query.conditions.ContainsOne; import org.nuiton.wikitty.entities.Element; +import org.nuiton.wikitty.query.WikittyQueryMaker; import org.nuiton.wikitty.query.conditions.Equals; import org.nuiton.wikitty.query.conditions.False; import org.nuiton.wikitty.query.conditions.Greater; @@ -84,16 +92,20 @@ protected ElementModifier elementModifier; protected String solrQuery = ""; + /** indique la profondeur de recherche en suivant les liens des champs de type wikitty */ + protected int wikittyFieldSearchDepth; public String getSolrQuery() { return solrQuery; } public WikittyQueryVisitorToSolr(WikittyTransaction tx, - WikittySearchEngineSolr solrServer, ElementModifier elementModifier) { + WikittySearchEngineSolr solrServer, ElementModifier elementModifier, + int wikittyFieldSearchDepth) { this.tx = tx; this.searchEngine = solrServer; this.elementModifier = elementModifier; + this.wikittyFieldSearchDepth = wikittyFieldSearchDepth; } /** @@ -219,6 +231,120 @@ return result; } + /** + * Si element2solr est de type Wikitty, alors on fait une recherche pour + * recuperer tous les ids des objets qui contiennent dans 1 de leur champs + * une valeur de l'argument values. + * + * La chaine retournee est (query OR element2solr:(valeur retournee par la recherche concatenee par de OR)) + * ou directement query si element2solr n'est pas de type Wikitty + * + * @param query la requete initial de l'utilisateur + * @param element2solr l'element sur lequel la requete est faite + * @param operator l'operateur pour concatener les sous requetes + * @param values les differentes valeurs a rechercher + * @return + */ + protected String deepSearchOnWikittyField(String query, String element2solr, String operator, Collection<String> values) { + if (log.isDebugEnabled()) { + log.debug("enter deepSearchOnWikittyField query: "+ query+ " element2solr:" + element2solr + " values:" + values); + } + if ( wikittyFieldSearchDepth > 0 ) { + // La recherche ce fait sur un champs de type wikitty, vu qu'on ne + // stocke que des id, si l'utilisateur passe autre chose, la recherche + // echouera. Ici on aide donc l'utilisateur en faisant pour lui + // la recherche sur les wikitties pour recuperer les ids qui pourraient + // convenir et faire la recherche sur ces ids + if (element2solr == null + || element2solr.endsWith(WikittySolrConstant.SUFFIX_WIKITTY) + || element2solr.startsWith(WikittySolrConstant.SOLR_ALL_EXTENSIONS) + || element2solr.startsWith(WikittySolrConstant.SOLR_FULLTEXT_ALL_EXTENSIONS) + ) { + + WikittyQuery sub = new WikittyQueryMaker() + .containsOne(Element.ALL_FIELD, values) + .end().setLimit(WikittyQuery.MAX) + .setWikittyFieldSearchDepth(wikittyFieldSearchDepth - 1); + // eval sub + WikittyQueryResult<String> subResult = + searchEngine.findAllByQuery(tx, sub); + + // si on a bien des resultat en plus on modifie la requete + if (subResult.size() > 0) { + query = "(" + query + " " + operator + " "; + // on ajoute les * car sinon pour la recherche fulltext + // solr modifie la requete et fini par retourne le monde + // entier lorsqu'on passe un id. Cela vient peut-etre de + // solr.WordDelimiterFilterFactory qui a un splitOnNumerics="1" + String subResultString = "*" + StringUtils.join(subResult, "* OR *") + "*"; + if (element2solr == null) { + query += "(" + subResultString + ")"; + } else { + query += element2solr + ":(" + subResultString + ")"; + } + query += ")"; + } + +// String subResult = ""; +// try { +// // on fait la recherhce le nombre de recursion demande +// Collection<String> currentValue = values; +// for (int i=0; i<wikittyFieldSearchDepth; i++) { +// System.out.println("## boucle " + i + " currentValue:" + currentValue); +// String queryString = ""; +// String sep = ""; +// for(String e : currentValue) { +// queryString += sep + e; +// sep = " OR "; +// } +// SolrQuery querySolr = new SolrQuery( +// WikittySolrConstant.SOLR_QUERY_PARSER + queryString); +// QueryResponse resp = SolrUtil.executeQuery( +// searchEngine.getSolrServer(), querySolr); +// SolrDocumentList solrResults = resp.getResults(); +// // Extract ids +// currentValue = new LinkedList<String>(); +// for (SolrDocument doc : solrResults) { +// String id = SolrUtil.getStringFieldValue(doc, WikittySolrConstant.SOLR_ID); +// currentValue.add(id); +// } +// } +// // a la suite de la derniere recursion on transforme en requete texte +// String sep = ""; +// for (String id : currentValue) { +// subResult += sep + "*" + escape2solr(id) + "*"; +// sep = " OR "; +// } +// +// } catch (Exception eee) { +// log.info("Can't make deep search on wikitty field, continue without", eee); +// } +// +// // si on a bien des resultat en plus on modifie la requete +// if (StringUtils.isNotBlank(subResult)) { +// query = "(" + query + " " + operator + " "; +// if (element2solr == null) { +// query += "(" + subResult + ")"; +// } else { +// query += element2solr + ":(" + subResult + ")"; +// } +// query += ")"; +// } + } + } + if(log.isDebugEnabled()) { + log.debug("exit deepSearchOnWikittyField query: "+ query); + } + return query; + } + /** + * + * @see {@link #deepSearchOnWikittyField(java.lang.String, java.lang.String, java.util.Collection) } + */ + protected String deepSearchOnWikittyField(String query, String element2solr, String operateur, String value) { + return deepSearchOnWikittyField(query, element2solr, operateur, Collections.singleton(value)); + } + @Override public void visit(ConditionValueString o) { // do nothing @@ -355,13 +481,27 @@ } else { String element2solr = element2solr(o.getElement()); - solrQuery += element2solr + ":("; + + // query contient ce qu'il faut ajouter a solrQuery + // on pre-calcul au cas ou il y aurait d'autres traitements a faire + // (pour les champs de type wikitty) + String query = element2solr + ":("; String sep = ""; for(String e : values) { - solrQuery += sep + fixSolrBug(element2solr, e); + query += sep + fixSolrBug(element2solr, e); sep = " OR "; } - solrQuery += ")"; + query += ")"; + + solrQuery += deepSearchOnWikittyField(query, element2solr, "OR", values); + +// solrQuery += element2solr + ":("; +// String sep = ""; +// for(String e : values) { +// solrQuery += sep + fixSolrBug(element2solr, e); +// sep = " OR "; +// } +// solrQuery += ")"; } return false; } @@ -390,7 +530,10 @@ value = fixSolrBug(element2solr, value); - solrQuery += element2solr + ":" + value; + String query = element2solr + ":" + value; + solrQuery += deepSearchOnWikittyField(query, element2solr, "OR", value); + +// solrQuery += element2solr + ":" + value; return false; } @@ -413,7 +556,9 @@ value= fixSolrBug(element2solr, value); - solrQuery += "-" + element2solr + ":" + value; + String query = "-" + element2solr + ":" + value; + solrQuery += deepSearchOnWikittyField(query, element2solr, "AND NOT", value); +// solrQuery += "-" + element2solr + ":" + value; return false; } @@ -463,7 +608,9 @@ // pour keyword on ajout automatiquement les *, sinon il faut faire un like value = "*" + value + "*"; - solrQuery += value; + String query = value; + solrQuery += deepSearchOnWikittyField(query, null, "OR", value); +// solrQuery += value; return false; } @@ -515,7 +662,9 @@ value = fixSolrBug(element2solr, value); - solrQuery += element2solr + ":" + value; + String query = element2solr + ":" + value; + solrQuery += deepSearchOnWikittyField(query, element2solr, "OR", value); +// solrQuery += element2solr + ":" + value; return false; } @@ -534,8 +683,9 @@ } value = fixSolrBug(element2solr, value); - - solrQuery += "-" + element2solr + ":" + value; + String query = "-" + element2solr + ":" + value; + solrQuery += deepSearchOnWikittyField(query, element2solr, "AND NOT", value); +// solrQuery += "-" + element2solr + ":" + value; return false; } Modified: trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java =================================================================== --- trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2012-05-31 15:03:05 UTC (rev 1477) +++ trunk/wikitty-solr/src/main/java/org/nuiton/wikitty/storage/solr/WikittySearchEngineSolr.java 2012-05-31 15:11:50 UTC (rev 1478) @@ -59,7 +59,6 @@ import org.nuiton.wikitty.entities.WikittyTreeNode; import org.nuiton.wikitty.entities.WikittyTreeNodeHelper; import org.nuiton.wikitty.entities.WikittyTypes; -import org.nuiton.wikitty.generator.WikittyTagValue; import org.nuiton.wikitty.query.FacetQuery; import org.nuiton.wikitty.query.FacetTopic; import org.nuiton.wikitty.query.WikittyQuery; @@ -90,6 +89,8 @@ final static private Log log = LogFactory.getLog(WikittySearchEngineSolr.class); final static private TimeLog timeLog = new TimeLog(WikittySearchEngineSolr.class); + protected ApplicationConfig config; + /** solr server */ protected SolrServer solrServer; @@ -117,6 +118,7 @@ // init system env solr.data.dir if (config != null) { + this.config = config; // choix du storage (file or Ram) String solrDirFactoryKey = WikittyConfigOption.WIKITTY_SEARCHENGINE_SOLR_DIRECTORY_FACTORY.getKey(); @@ -157,6 +159,14 @@ } } + public ApplicationConfig getConfig() { + return config; + } + + public SolrServer getSolrServer() { + return solrServer; + } + @Override public void clear(WikittyTransaction transaction) { try { @@ -665,7 +675,7 @@ // Create querySolr WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr( - transaction, this, elementModifier); + transaction, this, elementModifier, query.getWikittyFieldSearchDepth()); query.getCondition().accept(v); String queryString = v.getSolrQuery(); SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString); @@ -733,7 +743,7 @@ if (facetQuery != null) { for (FacetQuery facet : facetQuery) { v = new WikittyQueryVisitorToSolr( - transaction, this, elementModifier); + transaction, this, elementModifier, 0); // pas de recherche recursive sur les champs wikitty pour les facettes facet.getCondition().accept(v); String queryFacet = v.getSolrQuery(); facetQueryToName.put(queryFacet, facet.getName()); @@ -839,7 +849,7 @@ // et ses enfants jusqu'a la profondeur demandee // Create querySolr WikittyQueryVisitorToSolr v = new WikittyQueryVisitorToSolr( - transaction, this, elementModifier); + transaction, this, elementModifier, filter.getWikittyFieldSearchDepth()); treeQuery.getCondition().accept(v); String queryString = v.getSolrQuery(); SolrQuery querySolr = new SolrQuery(SOLR_QUERY_PARSER + queryString);
participants (1)
-
bpoussin@users.nuiton.org