1

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

但是,我想在某些情况下使用 Java,使用JCR API :javax.jcr.Nodejavax.jcr.NodeIterator

恐怕我会简单地通过自己编写代码来重新发明轮子。

是否有任何可用的东西(GistGithubelse

4

3 回答 3

2

您可以使用ItemVisitor递归遍历存储库,沿途收集与您的条件匹配的所有项目。

例如打印出 type 的所有属性Long

Node root = session.getRootNode();
root.accept(new ItemVisitor() {
    @Override
    public void visit(Property property) throws RepositoryException {
        if (!property.isMultiple() && property.getType() == PropertyType.LONG) {
             System.out.println(property.getName() + " = " + property.getLong());
        }
    }

    @Override
    public void visit(Node node1) throws RepositoryException {
        NodeIterator children = node1.getNodes();
        while (children.hasNext()) {
            visit(children.nextNode());
        }
    }
});
于 2017-03-23T08:01:34.447 回答
2

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

编辑

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

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

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

SlingQuery 是Apache Sling的一部分,这就是为什么 github 存储库似乎被放弃了。

注意:您可以静态导入美元符号并在您的语法中删除对 SlingQuery 的静态访问,例如 $(resource).find("...");

于 2016-12-22T12:59:59.527 回答
1

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

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


更多信息

Java 可能不是通过 JCR 搜索的最有效方式,因此请注意性能损失(与 using 相比JCR SQL2)。

但是,在某些情况下使用 JCR SQL2 会很烦人。例如:JCR SQL2 - JCR 浏览器中的结果查询顺序

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


解决方案

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

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);

资源:

于 2016-12-22T09:48:59.560 回答