if (filter.getFullTextConstraint() != null || (filter.getFulltextConditions() != null && filter.getFulltextConditions().size() > 0)) { if (filter.getPropertyRestrictions() != null && filter.getPropertyRestrictions().size() > 0 && (filter.getPropertyRestriction(NATIVE_SOLR_QUERY) != null || filter.getPropertyRestriction(NATIVE_LUCENE_QUERY) != null || configuration.useForPropertyRestrictions()) && !hasIgnoredProperties(filter.getPropertyRestrictions(), configuration)) { match++; if (filter.getPathRestriction() != null && !Filter.PathRestriction.NO_RESTRICTION.equals(filter.getPathRestriction()) && configuration.useForPathRestrictions()) { if (match > 0) { if (filter.getPrimaryTypes().size() > 0 && configuration.useForPrimaryTypes()) { if (match > 0) { match++;
PathIterator(Filter filter, String indexName, String pathPrefix, boolean prependPathPrefix) { this.filter = filter; this.pathPrefix = pathPrefix; this.indexName = indexName; boolean shouldDescendDirectly = filter.getPathRestriction().equals(Filter.PathRestriction.ALL_CHILDREN); if (shouldDescendDirectly) { filterPath = filter.getPath(); if (PathUtils.denotesRoot(filterPath)) { filterPath = ""; } } else { filterPath = ""; } parentPath = ""; currentPath = "/"; this.settings = filter.getQueryLimits(); this.prependPathPrefix = prependPathPrefix; }
private static void addNodeTypeConstraints(List<Query> qs, Filter filter) { BooleanQuery bq = new BooleanQuery(); for (String type : filter.getPrimaryTypes()) { bq.add(new TermQuery(new Term(JCR_PRIMARYTYPE, type)), SHOULD); } for (String type : filter.getMixinTypes()) { bq.add(new TermQuery(new Term(JCR_MIXINTYPES, type)), SHOULD); } qs.add(bq); }
@CheckForNull private static Set<String> getSuperTypes(Filter filter) { if (filter != null && !filter.matchesAllTypes()) { return filter.getSupertypes(); } return null; }
public boolean isPotentiallySlow(Filter filter, NodeState rootState) { if (filter.getFullTextConstraint() != null) { // not an appropriate index for full-text search return true; } if (filter.containsNativeConstraint()) { // not an appropriate index for native search return true; } if (filter.isAlwaysFalse()) { return false; } PathRestriction restriction = filter.getPathRestriction(); switch (restriction) { case EXACT: case PARENT: case DIRECT_CHILDREN: return false; case NO_RESTRICTION: case ALL_CHILDREN: return true; default: throw new IllegalArgumentException("Unknown restriction: " + restriction); } }
private boolean notSupportedFeature() { if(filter.getPathRestriction() == Filter.PathRestriction.NO_RESTRICTION && filter.matchesAllTypes() && filter.getPropertyRestrictions().isEmpty()) { //This mode includes name(), localname() queries //OrImpl [a/name] = 'Hello' or [b/name] = 'World' //Relative parent properties where [../foo1] is not null return true; } boolean failTestOnMissingFunctionIndex = true; if (failTestOnMissingFunctionIndex) { // this means even just function restrictions fail the test // (for example "where upper(name) = 'X'", // if a matching function-based index is missing return false; } // the following would ensure the test doesn't fail in that case: for (PropertyRestriction r : filter.getPropertyRestrictions()) { if (!r.propertyName.startsWith(QueryConstants.FUNCTION_RESTRICTION_PREFIX)) { // not a function restriction return false; } } return true; }
FullTextExpression ft = filter.getFullTextConstraint(); if (ft != null) { queryBuilder.append(parseFullTextExpression(ft, configuration)); queryBuilder.append(' '); } else if (filter.getFulltextConditions() != null) { Collection<String> fulltextConditions = filter.getFulltextConditions(); for (String fulltextCondition : fulltextConditions) { queryBuilder.append(fulltextCondition).append(" "); Collection<Filter.PropertyRestriction> propertyRestrictions = filter.getPropertyRestrictions(); if (propertyRestrictions != null && !propertyRestrictions.isEmpty()) { for (Filter.PropertyRestriction pr : propertyRestrictions) { String[] pts = filter.getPrimaryTypes().toArray(new String[filter.getPrimaryTypes().size()]); StringBuilder ptQueryBuilder = new StringBuilder(); for (int i = 0; i < pts.length; i++) { if (filter.getQueryStatement() != null && filter.getQueryStatement().contains(QueryConstants.REP_EXCERPT)) { if (!solrQuery.getHighlight()) { Filter.PathRestriction pathRestriction = filter.getPathRestriction(); if (pathRestriction != null) { String path = purgePath(filter, plan.getPathPrefix()); filter.getQueryStatement(), solrQuery.toString());
@Override public double getCost(Filter filter, NodeState root) { // TODO don't call getCost for such queries if (filter.getFullTextConstraint() != null) { // not an appropriate index for full-text search return POSITIVE_INFINITY; } if (filter.containsNativeConstraint()) { // not an appropriate index for native search return Double.POSITIVE_INFINITY; } for (PropertyRestriction pr : filter.getPropertyRestrictions()) { if (isEqualityRestrictionOnType(pr, REFERENCE) || isEqualityRestrictionOnType(pr, WEAKREFERENCE)) { return COST; } } // not an appropriate index return POSITIVE_INFINITY; }
private static void addNonFullTextConstraints(List<Query> qs, Filter filter, IndexReader reader, Analyzer analyzer, IndexDefinition indexDefinition) { if (!filter.matchesAllTypes()) { addNodeTypeConstraints(qs, filter); String path = filter.getPath(); switch (filter.getPathRestriction()) { case ALL_CHILDREN: if (USE_PATH_RESTRICTION) { for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
/** * Get the input value for a certain feature (by index) in the given filter. * <p/> * A filter is represented as a vector in R^5 where * i_0 : no. of property restrictions * i_1 : 1 if any native constraint exists in the filter, 0 otherwise * i_2 : the path restriction ordinal * i_3 : the depth of the path restriction if set, 0 otherwise * i_4 : the precedence of the dominant full text constraint if present, 0 otherwise * * @param filter the filter * @param i the index of the filter vector feature to retrieve * @return the feature value */ private long getInput(Filter filter, int i) { assert i < 5; if (i == 0) { return filter.getPropertyRestrictions() != null ? filter.getPropertyRestrictions().size() : 0; } else if (i == 1) { return filter.containsNativeConstraint() ? 1 : 0; } else if (i == 2) { return filter.getPathRestriction() != null ? filter.getPathRestriction().ordinal() : 0; } else if (i == 3) { return filter.getPathRestriction() != null ? filter.getPathRestriction().toString().split("/").length : 0; } else if (i == 4) { return filter.getFullTextConstraint() != null ? filter.getFullTextConstraint().getPrecedence() : 0; } return 0; } }
private static String extractUuidFromFilter(Filter filter) { Filter.PropertyRestriction restriction = filter .getPropertyRestriction("jcr:uuid"); return restriction.first.toString(); }
@Test public void testAllChildrenQueryParsing() throws Exception { String query = "select [jcr:path], [jcr:score], * from [nt:hierarchy] as a where isdescendantnode(a, '/')"; Filter filter = mock(Filter.class); OakSolrConfiguration configuration = new DefaultSolrConfiguration(){ @Override public boolean useForPathRestrictions() { return true; } }; when(filter.getQueryStatement()).thenReturn(query); Filter.PathRestriction pathRestriction = Filter.PathRestriction.ALL_CHILDREN; when(filter.getPathRestriction()).thenReturn(pathRestriction); when(filter.getPath()).thenReturn("/"); QueryIndex.IndexPlan plan = mock(QueryIndex.IndexPlan.class); SolrQuery solrQuery = FilterQueryParser.getQuery(filter, plan, configuration); assertNotNull(solrQuery); String[] filterQueries = solrQuery.getFilterQueries(); assertTrue(Arrays.asList(filterQueries).contains(configuration.getFieldForPathRestriction(pathRestriction) + ":\\/")); assertEquals("*:*", solrQuery.get("q")); }
@Override public Cursor query(Filter filter, NodeState root) { NodeTypeIndexLookup lookup = new NodeTypeIndexLookup(root, mountInfoProvider); if (!hasNodeTypeRestriction(filter) || !lookup.isIndexed(filter.getPath(), filter)) { throw new IllegalStateException( "NodeType index is used even when no index is available for filter " + filter); } return Cursors.newPathCursorDistinct(lookup.query(filter), filter.getQueryLimits()); }
@Override public Cursor query(Filter filter, NodeState root) { for (PropertyRestriction pr : filter.getPropertyRestrictions()) { if (isEqualityRestrictionOnType(pr, REFERENCE)) { String uuid = pr.first.getValue(STRING); String name = pr.propertyName; return lookup(root, uuid, name, REF_NAME, filter); } if (isEqualityRestrictionOnType(pr, WEAKREFERENCE)) { String uuid = pr.first.getValue(STRING); String name = pr.propertyName; return lookup(root, uuid, name, WEAK_REF_NAME, filter); } } return newPathCursor(new ArrayList<String>(), filter.getQueryLimits()); }
private boolean canEvalPathRestrictions(IndexingRule rule) { //Opt out if one is looking for all children for '/' as its equivalent to //NO_RESTRICTION if (filter.getPathRestriction() == Filter.PathRestriction.NO_RESTRICTION || (filter.getPathRestriction() == Filter.PathRestriction.ALL_CHILDREN && PathUtils.denotesRoot(filter.getPath())) ){ return false; } //If no other restrictions is provided and query is pure //path restriction based then need to be sure that index definition at least //allows indexing all the path for given nodeType return definition.evaluatePathRestrictions() && rule.indexesAllNodesOfMatchingType(); }
private static String purgePath(Filter filter, String pathPrefix) { String path = filter.getPath(); if (pathPrefix != null && pathPrefix.length() > 1 && path.startsWith(pathPrefix)) { path = path.substring(pathPrefix.length()); if (path.length() == 0) { path = "/"; } } return partialEscape(path).toString(); }
@Test public void oak4170() throws ParseException { String sql2 = "select * from [nt:unstructured] where CONTAINS([jcr:content/metadata/comment], 'december')"; Filter f = createFilterSQL(sql2); String plan = f.toString(); // with the "property is not null" restriction, it would be: // assertEquals("Filter(query=select * from [nt:unstructured] " + // "where CONTAINS([jcr:content/metadata/comment], 'december') " + // "fullText=jcr:content/metadata/comment:\"december\", " + // "path=*, property=[jcr:content/metadata/comment=[is not null]])", plan); assertEquals("Filter(query=select * from [nt:unstructured] " + "where CONTAINS([jcr:content/metadata/comment], 'december') " + "fullText=jcr:content/metadata/comment:\"december\", " + "path=*)", plan); assertEquals(f.getPropertyRestrictions().toString(), 0, f.getPropertyRestrictions().size()); f.getPropertyRestriction("jcr:content/metadata/comment"); }
private long estimatedEntryCount_Compat(int numOfDocs) { //Other index only compete in case of property indexes. For fulltext //index return true count so as to allow multiple property indexes //to be compared fairly FullTextExpression ft = filter.getFullTextConstraint(); if (ft != null && definition.isFullTextEnabled()){ return definition.getFulltextEntryCount(numOfDocs); } return Math.min(definition.getEntryCount(), numOfDocs); }
@Override public Cursor query(final IndexPlan plan, final NodeState root) { Cursor cursor; try { Filter filter = plan.getFilter(); final Set<String> relPaths = filter.getFullTextConstraint() != null ? getRelativePaths(filter.getFullTextConstraint()) : Collections.<String>emptySet(); final String parent = relPaths.size() == 0 ? "" : relPaths.iterator().next(); final int parentDepth = getDepth(parent); String path = plan.getPlanName(); OakSolrConfiguration configuration = getConfiguration(path, root); SolrClient solrServer = getServer(path, root); LMSEstimator estimator = getEstimator(path); AbstractIterator<SolrResultRow> iterator = getIterator(filter, plan, parent, parentDepth, configuration, solrServer, estimator); cursor = new SolrRowCursor(iterator, plan, filter.getQueryLimits(), estimator, solrServer, configuration); } catch (Exception e) { throw new RuntimeException(e); } return cursor; }
@Override public List<IndexPlan> getPlans(Filter filter, List<OrderEntry> sortOrder, NodeState rootState) { FullTextExpression ft = filter.getFullTextConstraint(); if (ft == null) { LOG.warn("More than one relative parent for query " + filter.getQueryStatement());