通过java在JCR repo中进行递归搜索

时间:2016-12-21 16:11:47

标签: java search recursion jcr jcr-sql2

我知道如何通过JCR JCR SQL2 queries 中搜索某些内容。

但是,我想在某些情况下使用Java,使用JCR APIjavax.jcr.Nodejavax.jcr.NodeIterator等。

我担心我会通过自己的编码来重新发明轮子。

是否有任何可用的内容(GistGithubelse)?

3 个答案:

答案 0 :(得分:2)

您可以使用SlingQuery。它受jQuery的启发并遵循它的语法。您应该仅使用它来搜索少量节点(最好在100以下),因为遍历查询很慢。

修改

您的示例可能会转换为以下SlingQueries(未经测试):

SlingQuery.$(startResource).find("[name=teasers][title=awesome-teaser]")

SlingQuery.$(startResource).find("[name][controlName]")

SlingQuery是Apache Sling的一部分,因为有一段时间,这就是github存储库似乎被放弃的原因。

注意:您可以静态导入Dollar符号并使用语法删除SlingQuery上的静态访问,例如$(resource).find(" ...");

答案 1 :(得分:1)

我最终编写了自己的实现。

随意改进或添加评论以获得潜在的改进。

更多信息

Java可能不是搜索JCR的最有效方式,因此请注意性能损失(使用JCR SQL2)。

但是,有些情况下使用JCR SQL2会比较烦人。例如:JCR SQL2 - result query order as in JCR browser

我建议您在树中尽可能低地启动搜索。

解决方案

阅读上述每种方法的评论以找到更多信息。

package com.nameoforganization.jcr;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class JcrSearchUtils {

    private static final Logger log = LoggerFactory.getLogger(JcrUtil.class);

    /*
     * Recursive search in JCR tree: properties matching values
     * Parameters:
     *  - node: node to start the search from
     *  - propertyValueConditions: properties searched along with the value expected for it
     *  - searchResults: set this to null when launching the search
     */
    public static ArrayList<Node> searchRecursivelyPropMatchVal(Node node, HashMap<String, String> propertyValueConditions, ArrayList<Node> searchResults) {
        if(searchResults == null){
            searchResults = new ArrayList<Node>();
        }
        try{    
            NodeIterator list = node.getNodes();

            while(list.hasNext())   {

                Node currentSubNode = list.nextNode();
                Boolean hasAllRequiredPropsAndVals = true;

                for (Map.Entry<String, String> entry : propertyValueConditions.entrySet()) {
                    String propertyName = entry.getKey();
                    Object searchedValue = entry.getValue();
                    if ( !currentSubNode.hasProperty(propertyName) || !currentSubNode.getProperty(propertyName).getString().equals(searchedValue) ){
                        hasAllRequiredPropsAndVals = false;
                    }                   
                }
                if ( hasAllRequiredPropsAndVals ){
                    searchResults.add(currentSubNode);
                }

                searchRecursivelyPropMatchVal(currentSubNode, propertyValueConditions, searchResults);
            }

            return searchResults;
        } catch (RepositoryException rpe){
            log.info("Recursive search in JCR tree (properties matching values) via JCR API failed");
        }
        return null;
    }


    /*
     * Recursive search in JCR tree: required properties present 
     * Parameters:
     *  - node: node to start the search from
     *  - propertyValueConditions: properties searched along with the value expected for it
     *  - searchResults: set this to null when launching the search
     */
    public static ArrayList<Node> searchRecursivelyPropPres(Node node, ArrayList<String> propertyPresConditions, ArrayList<Node> searchResults) {
        if(searchResults == null){
            searchResults = new ArrayList<Node>();
        }
        try{    
            NodeIterator list = node.getNodes();

            while(list.hasNext())   {

                Node currentSubNode = list.nextNode();
                Boolean hasAllRequiredProperties = true;

                for (String propertyName : propertyPresConditions) {
                    if ( !currentSubNode.hasProperty(propertyName) ){
                        hasAllRequiredProperties = false;
                    }
                }
                if( hasAllRequiredProperties ){
                    searchResults.add(currentSubNode);
                }

                searchRecursivelyPropPres(currentSubNode, propertyPresConditions, searchResults);
            }

            return searchResults;
        } catch (RepositoryException rpe){
            log.info("Recursive search in JCR tree (required properties present) via JCR API failed");
        }
        return null;
    }


}

第一种实用方法的用法

    /*
     *  Search nodes with properties:
     *  "name" having value "teasers"
     *  "title" having value "awesome-teaser"
     */
    // Node startingNode = set this yourself :)
    HashMap<String, String> propertyValueConditions = new HashMap<String, String>();
    propertyValueConditions.put("name", "teasers");
    propertyValueConditions.put("title", "awesome-teaser");
    ArrayList<Node> nodesFound = JcrUtil.searchRecursivelyPropMatchVal(startingNode, propertyValueConditions, null);

第二种实用方法的用法

    /*
     *  Search nodes having properties "name" and "controlName"
     */
    // Node startingNode = set this yourself :)
    ArrayList<String> propertyPresConditions = new ArrayList<String>();
    propertyPresConditions.add("name");
    propertyPresConditions.add("controlName");
    ArrayList<Node> nodesFound = JcrUtil.searchRecursivelyPropPres(startingNode, propertyPresConditions, null);

资源:

答案 2 :(得分:1)

您可以使用ItemVisitor递归遍历存储库,收集符合您标准的所有项目。

E.g。打印出class UserMailer < ApplicationMailer def try_notif(notification, post, user) @notification = notification @post = post @user = user mail(to: @post.user.email, subject: 'New Notification') end end 类型的所有属性:

Long