Example #1
0
  /**
   * This method searches across multiple indexes and combines the answers. Create the business
   * object and only initialize the attributes you want to actually use in the query. You can AND or
   * OR all these attributes.
   *
   * @param criteria A business object with only attributes in the query set. Others must be null
   * @param isAND TRUE if results are to be ANDed otherwise the results are ORed
   * @return The list of keys for the matching entries @See TestSubstringIndex
   */
  public SearchResult<RK> searchMultipleIndexes(A criteria, boolean isAND) {
    try {
      Set<ByteArrayKey> result = null;
      // first run the individual queries for each attribute in parallel
      Collection<Future<SearchResult<byte[]>>> threads =
          new ArrayList<Future<SearchResult<byte[]>>>();
      for (Field f : indexedFields) {
        final String value = (String) f.get(criteria); // non null field means it's in the query
        if (value != null) {
          final Index<A, RK> index = getIndex(f.getName());

          Callable<SearchResult<byte[]>> c =
              new Callable<SearchResult<byte[]>>() {
                public SearchResult<byte[]> call() {
                  SearchResult<byte[]> r = index.rawContains(value);
                  return r;
                }
              };

          Future<SearchResult<byte[]>> future = utils.getExecutorService().submit(c);
          threads.add(future);
        }
      }
      // the collect the results and AND/OR them
      for (Future<SearchResult<byte[]>> future : threads) {
        SearchResult<byte[]> r = future.get();
        if (!r.isTooManyMatches()) {
          Collection<ByteArrayKey> rr = convertToKeys(r.getResults());
          if (result == null) result = new HashSet<ByteArrayKey>(rr);
          else if (isAND) {
            // AND this index match with the current running results
            LinkedList<ByteArrayKey> removeList = new LinkedList<ByteArrayKey>();
            for (ByteArrayKey k : rr) {
              if (!result.contains(k)) removeList.add(k);
            }
            for (ByteArrayKey k : result) {
              if (!rr.contains(k)) removeList.add(k);
            }
            result.removeAll(removeList);
          } else result.addAll(rr);
        }
      }
      if (result != null) {
        Map<ByteArrayKey, RK> rc =
            utils.getAll(result, utils.getObjectGrid().getMap(internalKeyToRealKeyMapName));
        return new SearchResult<RK>(new ArrayList<RK>(rc.values()));
      } else return new SearchResult<RK>();
    } catch (Exception e) {
      throw new ObjectGridRuntimeException(e);
    }
  }