Hello, Vadim,
      Thank you for the message.
      I think search over multiple collections of similar document is a needed
feature. By partitioning the database into smaller collections may improve the
performance. I have documents to store in a collection tree like:

       /db/proposals
             /VLA
                 /200402
                 /200406
                 /200410
             /VLBA
                 /200402
                 /200406
                 /200410
             /EVLA
                 /200402
                 /200406
                 /200410
             /GBT
                 /200402
                 /200406
                 /200410

I modified XPathQuery.java to do multiple collection search.
     The are 2 ways to specified a collection list. The first uses a comma or 
semi-colon
separated list, for example:
     xindice xpath -c 
xmldb:xindice://localhost:8080/db/proposals/VLA/200402;xmldb:xindice://localhost:8080/db/proposals/VLBA/200406

     The second uses * to indicate all the child collections, for example
     xindice xpath -c xmldb:xindice://localhost:8080/db/proposals/*/200402
or
     xindice xpath -c xmldb:xindice://localhost:8080/db/proposals/VLA/*

The combination of the 2 way also ok.

     Attached XPathQuery.java contains my modification to the original file.
I added 2 private functions to extract collection list and modified execute
method to loop over all the collection list.

     I am new to xindice and am not sure if this modification make sense or
if it has impact on other modules.


Honglin Ye National Radio Astronomy Observatory Socorro, NM USA





























Honglin Ye wrote:

> Honglin Ye wrote:
>
>> Is it possible to query db over multiple collection?
>>
>> For exacmple
>>
>> xindice xpath -c xmldb:xindice://host:8080/db/root/ -q "/root/childre"
>>
> sorry, it should read
>
> xindice xpath -c xmldb:xindice://host:8080/db/root/* -q "/root/childre"



See Xindice website, Todo page:
   <strong>The Query Engine</strong> The query engine has basic
   functionality right now.  Indexing and XPath query work against a
   Collection, but no unified cross-Collection query system currently
   exists.

In short:
No, Xindice currently does not support quering over multiple connections. You 
are welcome to enhance Xindice and send in a patch.

Thanks,
Vadim




/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xindice" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999-2001, The dbXML
 * Group, L.L.C., http://www.dbxmlgroup.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * CVS $Id: XPathQuery.java,v 1.11 2003/08/12 02:57:30 vladimir Exp $
 */

package org.apache.xindice.tools.command;

import org.apache.xindice.tools.XMLTools;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XPathQueryService;

import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.ArrayList;

/**
 * SingleDocumentQuery is designed to enable the user/admin to XPathQuery
 * a Collection for a Single Document.
 *
 * @version CVS $Revision: 1.11 $, $Date: 2003/08/12 02:57:30 $
 */
public class XPathQuery extends Command {

    private static final Log log = LogFactory.getLog(XPathQuery.class);

    public boolean execute(Hashtable table) throws Exception {

        Collection col = null;
        try {
            if ((String) table.get(XMLTools.COLLECTION) == null) {
                System.out.println("ERROR : Collection name and switch required");
                return false;
            }

            if ((String) table.get(XMLTools.QUERY) == "") {
                System.out.println("ERROR : Query and switch required");
                return false;
            }

            String querystring = (String) table.get(XMLTools.QUERY);
            XPathQueryService service = null;
            ResourceIterator results = null;

            ArrayList colList = new ArrayList(3);
            getCollectionList(table, colList);
            System.out.println("colList size=" + colList.size());
            for (int i = 0; i < colList.size(); i++) {
              String aCol = (String)colList.get(i);
              String colstring = normalizeCollectionURI(aCol, (String) table.get(XMLTools.LOCAL));

              col = DatabaseManager.getCollection(colstring);
              System.out.println("colstring=" + colstring);
              if (col == null) {
                System.out.println("ERROR : Collection not found!");
                return false;
              }

              service = (XPathQueryService) col.getService("XPathQueryService", "1.0");
              addNamespaces(service, (String) table.get("namespaces"));

              ResourceSet resultSet = service.query(querystring);
              results = resultSet.getIterator();

              while (results.hasMoreResources()) {
                XMLResource resource = (XMLResource) results.nextResource();
                String documentstr = (String) resource.getContent();
                System.out.println(documentstr);
              }
            }

        } catch (Exception e) {
            System.out.println("ERROR : " + e.getMessage());
            if (table.get(XMLTools.VERBOSE).equals("true")) {
                if (log.isWarnEnabled()) {
                    log.warn("ignored exception", e);
                }
            }
            return false;

        } finally {
            if (col != null) {
                col.close();
            }
        }

        return true;
    }

    private void addNamespaces(XPathQueryService service, String namespacesString) throws XMLDBException {
        if ((namespacesString != "") && (namespacesString != null)) {
            StringTokenizer st = new StringTokenizer(namespacesString, "=;");
            if (st.countTokens() % 2 != 0) {
                System.out.println("ERROR : mismatched namespace prefixes and uris");
                return;
            }
            while (st.hasMoreTokens()) {
                service.setNamespace(st.nextToken(), st.nextToken());
            }
        }
    }
    private void getCollectionList(Hashtable table, ArrayList workTable) {
      String col = (String) table.get(XMLTools.COLLECTION);
      StringTokenizer tok = new StringTokenizer(col, ";, ");
      for (int i = 0; tok.hasMoreTokens(); i++) {
        workTable.add(tok.nextToken());
      }
      expandColStr(table, workTable);

    }
    private void expandColStr(Hashtable table, ArrayList workTable) {
      for (int i = 0; i < workTable.size(); i++) {
        String argStr = (String)workTable.get(i);
        int starPos = argStr.indexOf("/*");
        if (starPos > 0) {
          String head = argStr.substring(0, starPos);
          String tail = argStr.substring(starPos + 2);
          String[] children = getChildCollections(table, head);
          if (children != null && children.length > 0) {
            workTable.remove(i);
            for (int j = 0; j < children.length; j++) {
              workTable.add(head + "/" + children[j] + tail);
            }
            expandColStr(table, workTable);
          }
        }
      }
    }
    private String[] getChildCollections(Hashtable table, String parent) {
      Collection coll = null;
      String[] colarray = null;
      String colstring = normalizeCollectionURI(parent,
          (String) table.get(XMLTools.LOCAL));
      try {
        coll = DatabaseManager.getCollection(colstring);
        if (coll != null) {
          colarray = coll.listChildCollections();
        }
      }
      catch (XMLDBException ex) {
      }
      finally {
        if (coll != null) {
          try {
            coll.close();
          }
          catch (XMLDBException ex) {
          }
        }
      }
      return colarray;
    }
}

Reply via email to