List of usage examples for com.mongodb.client.model Aggregates project
public static Bson project(final Bson projection)
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Create a pipeline query node based on a StatementPattern. * @param collection The collection of triples to query. * @param baseSP The leaf node in the query tree. *///from www. j av a 2 s . c o m public AggregationPipelineQueryNode(final MongoCollection<Document> collection, final StatementPattern baseSP) { this.collection = Preconditions.checkNotNull(collection); Preconditions.checkNotNull(baseSP); this.varToOriginalName = HashBiMap.create(); final StatementVarMapping mapping = new StatementVarMapping(baseSP, varToOriginalName); this.assuredBindingNames = new HashSet<>(mapping.varNames()); this.bindingNames = new HashSet<>(mapping.varNames()); this.pipeline = new LinkedList<>(); this.pipeline.add(Aggregates.match(getMatchExpression(baseSP))); this.pipeline.add(Aggregates.project(mapping.getProjectExpression())); }
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Add a join with an individual {@link StatementPattern} to the pipeline. * @param sp The statement pattern to join with * @return true if the join was successfully added to the pipeline. *///from ww w . ja v a 2 s .c o m public boolean joinWith(final StatementPattern sp) { Preconditions.checkNotNull(sp); // 1. Determine shared variables and new variables final StatementVarMapping spMap = new StatementVarMapping(sp, varToOriginalName); final NavigableSet<String> sharedVars = new ConcurrentSkipListSet<>(spMap.varNames()); sharedVars.retainAll(assuredBindingNames); // 2. Join on one shared variable final String joinKey = sharedVars.pollFirst(); final String collectionName = collection.getNamespace().getCollectionName(); Bson join; if (joinKey == null) { return false; } else { join = Aggregates.lookup(collectionName, HASHES + "." + joinKey, spMap.hashField(joinKey), JOINED_TRIPLE); } pipeline.add(join); // 3. Unwind the joined triples so each document represents a binding // set (solution) from the base branch and a triple that may match. pipeline.add(Aggregates.unwind("$" + JOINED_TRIPLE)); // 4. (Optional) If there are any shared variables that weren't used as // the join key, project all existing fields plus a new field that // tests the equality of those shared variables. final BasicDBObject matchOpts = getMatchExpression(sp, JOINED_TRIPLE); if (!sharedVars.isEmpty()) { final List<Bson> eqTests = new LinkedList<>(); for (final String varName : sharedVars) { final String oldField = valueFieldExpr(varName); final String newField = joinFieldExpr(spMap.valueField(varName)); final Bson eqTest = new Document("$eq", Arrays.asList(oldField, newField)); eqTests.add(eqTest); } final Bson eqProjectOpts = Projections.fields(Projections.computed(FIELDS_MATCH, Filters.and(eqTests)), Projections.include(JOINED_TRIPLE, VALUES, HASHES, TYPES, LEVEL, TIMESTAMP)); pipeline.add(Aggregates.project(eqProjectOpts)); matchOpts.put(FIELDS_MATCH, true); } // 5. Filter for solutions whose triples match the joined statement // pattern, and, if applicable, whose additional shared variables // match the current solution. pipeline.add(Aggregates.match(matchOpts)); // 6. Project the results to include variables from the new SP (with // appropriate renaming) and variables referenced only in the base // pipeline (with previous names). final Bson finalProjectOpts = new StatementVarMapping(sp, varToOriginalName) .getProjectExpression(assuredBindingNames, str -> joinFieldExpr(str)); assuredBindingNames.addAll(spMap.varNames()); bindingNames.addAll(spMap.varNames()); pipeline.add(Aggregates.project(finalProjectOpts)); return true; }
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Add a SPARQL projection or multi-projection operation to the pipeline. * The number of documents produced by the pipeline after this operation * will be the number of documents entering this stage (the number of * intermediate results) multiplied by the number of * {@link ProjectionElemList}s supplied here. Empty projections are * unsupported; if one or more projections given binds zero variables, then * the pipeline will be unchanged and the method will return false. * @param projections One or more projections, i.e. mappings from the result * at this stage of the query into a set of variables. * @return true if the projection(s) were added to the pipeline. *//*w ww . ja v a 2 s .c o m*/ public boolean project(final Iterable<ProjectionElemList> projections) { if (projections == null || !projections.iterator().hasNext()) { return false; } final List<Bson> projectOpts = new LinkedList<>(); final Set<String> bindingNamesUnion = new HashSet<>(); Set<String> bindingNamesIntersection = null; for (final ProjectionElemList projection : projections) { if (projection.getElements().isEmpty()) { // Empty projections are unsupported -- fail when seen return false; } final Document valueDoc = new Document(); final Document hashDoc = new Document(); final Document typeDoc = new Document(); final Set<String> projectionBindingNames = new HashSet<>(); for (final ProjectionElem elem : projection.getElements()) { String to = elem.getTargetName(); // If the 'to' name is invalid, replace it internally if (!isValidFieldName(to)) { to = replace(to); } String from = elem.getSourceName(); // If the 'from' name is invalid, use the internal substitute if (varToOriginalName.containsValue(from)) { from = varToOriginalName.inverse().get(from); } projectionBindingNames.add(to); if (to.equals(from)) { valueDoc.append(to, 1); hashDoc.append(to, 1); typeDoc.append(to, 1); } else { valueDoc.append(to, valueFieldExpr(from)); hashDoc.append(to, hashFieldExpr(from)); typeDoc.append(to, typeFieldExpr(from)); } } bindingNamesUnion.addAll(projectionBindingNames); if (bindingNamesIntersection == null) { bindingNamesIntersection = new HashSet<>(projectionBindingNames); } else { bindingNamesIntersection.retainAll(projectionBindingNames); } projectOpts.add(new Document().append(VALUES, valueDoc).append(HASHES, hashDoc).append(TYPES, typeDoc) .append(LEVEL, "$" + LEVEL).append(TIMESTAMP, "$" + TIMESTAMP)); } if (projectOpts.size() == 1) { pipeline.add(Aggregates.project(projectOpts.get(0))); } else { final String listKey = "PROJECTIONS"; final Bson projectIndividual = Projections.fields( Projections.computed(VALUES, "$" + listKey + "." + VALUES), Projections.computed(HASHES, "$" + listKey + "." + HASHES), Projections.computed(TYPES, "$" + listKey + "." + TYPES), Projections.include(LEVEL), Projections.include(TIMESTAMP)); pipeline.add(Aggregates.project(Projections.computed(listKey, projectOpts))); pipeline.add(Aggregates.unwind("$" + listKey)); pipeline.add(Aggregates.project(projectIndividual)); } assuredBindingNames.clear(); bindingNames.clear(); assuredBindingNames.addAll(bindingNamesIntersection); bindingNames.addAll(bindingNamesUnion); return true; }
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Add a SPARQL extension to the pipeline, if possible. An extension adds * some number of variables to the result. Adds a "$project" step to the * pipeline, but differs from the SPARQL project operation in that * 1) pre-existing variables are always kept, and 2) values of new variables * are defined by expressions, which may be more complex than simply * variable names. Not all expressions are supported. If unsupported * expression types are used in the extension, the pipeline will remain * unchanged and this method will return false. * @param extensionElements A list of new variables and their expressions * @return True if the extension was successfully converted into a pipeline * step, false otherwise./*from w ww .j a v a2s . c om*/ */ public boolean extend(final Iterable<ExtensionElem> extensionElements) { final List<Bson> valueFields = new LinkedList<>(); final List<Bson> hashFields = new LinkedList<>(); final List<Bson> typeFields = new LinkedList<>(); for (final String varName : bindingNames) { valueFields.add(Projections.include(varName)); hashFields.add(Projections.include(varName)); typeFields.add(Projections.include(varName)); } final Set<String> newVarNames = new HashSet<>(); for (final ExtensionElem elem : extensionElements) { String name = elem.getName(); if (!isValidFieldName(name)) { // If the field name is invalid, replace it internally name = replace(name); } // We can only handle certain kinds of value expressions; return // failure for any others. final ValueExpr expr = elem.getExpr(); final Object valueField; final Object hashField; final Object typeField; if (expr instanceof Var) { final String varName = ((Var) expr).getName(); valueField = "$" + varName; hashField = "$" + varName; typeField = "$" + varName; } else if (expr instanceof ValueConstant) { final Value val = ((ValueConstant) expr).getValue(); valueField = new Document("$literal", val.stringValue()); hashField = new Document("$literal", SimpleMongoDBStorageStrategy.hash(val.stringValue())); if (val instanceof Literal) { typeField = new Document("$literal", ((Literal) val).getDatatype().stringValue()); } else { typeField = null; } } else { // if not understood, return failure return false; } valueFields.add(Projections.computed(name, valueField)); hashFields.add(Projections.computed(name, hashField)); if (typeField != null) { typeFields.add(Projections.computed(name, typeField)); } newVarNames.add(name); } assuredBindingNames.addAll(newVarNames); bindingNames.addAll(newVarNames); final Bson projectOpts = Projections.fields(Projections.computed(VALUES, Projections.fields(valueFields)), Projections.computed(HASHES, Projections.fields(hashFields)), Projections.computed(TYPES, Projections.fields(typeFields)), Projections.include(LEVEL), Projections.include(TIMESTAMP)); pipeline.add(Aggregates.project(projectOpts)); return true; }
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Add a SPARQL filter to the pipeline, if possible. A filter eliminates * results that don't satisfy a given condition. Not all conditional * expressions are supported. If unsupported expressions are used in the * filter, the pipeline will remain unchanged and this method will return * false. Currently only supports binary {@link Compare} conditions among * variables and/or literals.//w w w . ja v a 2 s .c om * @param condition The filter condition * @return True if the filter was successfully converted into a pipeline * step, false otherwise. */ public boolean filter(final ValueExpr condition) { if (condition instanceof Compare) { final Compare compare = (Compare) condition; final Compare.CompareOp operator = compare.getOperator(); final Object leftArg = valueFieldExpr(compare.getLeftArg()); final Object rightArg = valueFieldExpr(compare.getRightArg()); if (leftArg == null || rightArg == null) { // unsupported value expression, can't convert filter return false; } final String opFunc; switch (operator) { case EQ: opFunc = "$eq"; break; case NE: opFunc = "$ne"; break; case LT: opFunc = "$lt"; break; case LE: opFunc = "$le"; break; case GT: opFunc = "$gt"; break; case GE: opFunc = "$ge"; break; default: // unrecognized comparison operator, can't convert filter return false; } final Document compareDoc = new Document(opFunc, Arrays.asList(leftArg, rightArg)); pipeline.add(Aggregates.project(Projections.fields(Projections.computed("FILTER", compareDoc), Projections.include(VALUES, HASHES, TYPES, LEVEL, TIMESTAMP)))); pipeline.add(Aggregates.match(new Document("FILTER", true))); pipeline.add(Aggregates .project(Projections.fields(Projections.include(VALUES, HASHES, TYPES, LEVEL, TIMESTAMP)))); return true; } return false; }
From source file:org.apache.rya.mongodb.aggregation.AggregationPipelineQueryNode.java
License:Apache License
/** * Given that the current state of the pipeline produces data that can be * interpreted as triples, add a project step to map each result from the * intermediate result structure to a structure that can be stored in the * triple store. Does not modify the internal pipeline, which will still * produce intermediate results suitable for query evaluation. * @param timestamp Attach this timestamp to the resulting triples. * @param requireNew If true, add an additional step to check constructed * triples against existing triples and only include new ones in the * result. Adds a potentially expensive $lookup step. * @throws IllegalStateException if the results produced by the current * pipeline do not have variable names allowing them to be interpreted as * triples (i.e. "subject", "predicate", and "object"). *///w ww .jav a 2 s . co m public List<Bson> getTriplePipeline(final long timestamp, final boolean requireNew) { if (!assuredBindingNames.contains(SUBJECT) || !assuredBindingNames.contains(PREDICATE) || !assuredBindingNames.contains(OBJECT)) { throw new IllegalStateException("Current pipeline does not produce " + "records that can be converted into triples.\n" + "Required variable names: <" + SUBJECT + ", " + PREDICATE + ", " + OBJECT + ">\nCurrent variable names: " + assuredBindingNames); } final List<Bson> triplePipeline = new LinkedList<>(pipeline); final List<Bson> fields = new LinkedList<>(); fields.add(Projections.computed(SUBJECT, valueFieldExpr(SUBJECT))); fields.add(Projections.computed(SUBJECT_HASH, hashFieldExpr(SUBJECT))); fields.add(Projections.computed(PREDICATE, valueFieldExpr(PREDICATE))); fields.add(Projections.computed(PREDICATE_HASH, hashFieldExpr(PREDICATE))); fields.add(Projections.computed(OBJECT, valueFieldExpr(OBJECT))); fields.add(Projections.computed(OBJECT_HASH, hashFieldExpr(OBJECT))); fields.add(Projections.computed(OBJECT_TYPE, ConditionalOperators.ifNull(typeFieldExpr(OBJECT), DEFAULT_TYPE))); fields.add(Projections.computed(OBJECT_LANGUAGE, hashFieldExpr(OBJECT))); fields.add(Projections.computed(CONTEXT, DEFAULT_CONTEXT)); fields.add(Projections.computed(STATEMENT_METADATA, DEFAULT_METADATA)); fields.add(DEFAULT_DV); fields.add(Projections.computed(TIMESTAMP, new Document("$literal", timestamp))); fields.add(Projections.computed(LEVEL, new Document("$add", Arrays.asList("$" + LEVEL, 1)))); triplePipeline.add(Aggregates.project(Projections.fields(fields))); if (requireNew) { // Prune any triples that already exist in the data store final String collectionName = collection.getNamespace().getCollectionName(); final Bson includeAll = Projections.include(SUBJECT, SUBJECT_HASH, PREDICATE, PREDICATE_HASH, OBJECT, OBJECT_HASH, OBJECT_TYPE, OBJECT_LANGUAGE, CONTEXT, STATEMENT_METADATA, DOCUMENT_VISIBILITY, TIMESTAMP, LEVEL); final List<Bson> eqTests = new LinkedList<>(); eqTests.add(new Document("$eq", Arrays.asList("$$this." + PREDICATE_HASH, "$" + PREDICATE_HASH))); eqTests.add(new Document("$eq", Arrays.asList("$$this." + OBJECT_HASH, "$" + OBJECT_HASH))); final Bson redundantFilter = new Document("$filter", new Document("input", "$" + JOINED_TRIPLE) .append("as", "this").append("cond", new Document("$and", eqTests))); triplePipeline.add(Aggregates.lookup(collectionName, SUBJECT_HASH, SUBJECT_HASH, JOINED_TRIPLE)); final String numRedundant = "REDUNDANT"; triplePipeline.add(Aggregates.project(Projections.fields(includeAll, Projections.computed(numRedundant, new Document("$size", redundantFilter))))); triplePipeline.add(Aggregates.match(Filters.eq(numRedundant, 0))); triplePipeline.add(Aggregates.project(Projections.fields(includeAll))); } return triplePipeline; }
From source file:org.opencb.cellbase.lib.impl.GeneMongoDBAdaptor.java
License:Apache License
@Override public QueryResult getTfbs(Query query, QueryOptions queryOptions) { Bson bsonQuery = parseQuery(query);/*from w w w. jav a 2 s . co m*/ Bson match = Aggregates.match(bsonQuery); // We parse user's exclude options, ONLY _id can be added if exists Bson includeAndExclude; Bson exclude = null; if (queryOptions != null && queryOptions.containsKey("exclude")) { List<String> stringList = queryOptions.getAsStringList("exclude"); if (stringList.contains("_id")) { exclude = Aggregates.project(Projections.exclude("_id")); } } if (exclude != null) { includeAndExclude = Aggregates .project(Projections.fields(Projections.excludeId(), Projections.include("transcripts.tfbs"))); } else { includeAndExclude = Aggregates.project(Projections.include("transcripts.tfbs")); } Bson unwind = Aggregates.unwind("$transcripts"); Bson unwind2 = Aggregates.unwind("$transcripts.tfbs"); // This project the three fields of Xref to the top of the object Document document = new Document("tfName", "$transcripts.tfbs.tfName"); document.put("pwm", "$transcripts.tfbs.pwm"); document.put("chromosome", "$transcripts.tfbs.chromosome"); document.put("start", "$transcripts.tfbs.start"); document.put("end", "$transcripts.tfbs.end"); document.put("strand", "$transcripts.tfbs.strand"); document.put("relativeStart", "$transcripts.tfbs.relativeStart"); document.put("relativeEnd", "$transcripts.tfbs.relativeEnd"); document.put("score", "$transcripts.tfbs.score"); Bson project = Aggregates.project(document); return mongoDBCollection.aggregate(Arrays.asList(match, includeAndExclude, unwind, unwind2, project), queryOptions); }
From source file:org.opencb.cellbase.lib.impl.MongoDBAdaptor.java
License:Apache License
protected QueryResult groupBy(Bson query, String groupByField, String featureIdField, QueryOptions options) { if (groupByField == null || groupByField.isEmpty()) { return new QueryResult(); }/*from www . j a v a 2 s .c o m*/ if (groupByField.contains(",")) { // call to multiple groupBy if commas are present return groupBy(query, Arrays.asList(groupByField.split(",")), featureIdField, options); } else { Bson match = Aggregates.match(query); Bson project = Aggregates.project(Projections.include(groupByField, featureIdField)); Bson group; if (options.getBoolean("count", false)) { group = Aggregates.group("$" + groupByField, Accumulators.sum("count", 1)); return mongoDBCollection.aggregate(Arrays.asList(match, project, group), options); } else { // Limit the documents passed if count is false Bson limit = Aggregates.limit(options.getInt("limit", 10)); group = Aggregates.group("$" + groupByField, Accumulators.addToSet("features", "$" + featureIdField)); // TODO change the default "_id" returned by mongodb to id return mongoDBCollection.aggregate(Arrays.asList(match, limit, project, group), options); } } }
From source file:org.opencb.cellbase.lib.impl.MongoDBAdaptor.java
License:Apache License
protected QueryResult groupBy(Bson query, List<String> groupByField, String featureIdField, QueryOptions options) {// w w w . java 2 s . c om if (groupByField == null || groupByField.isEmpty()) { return new QueryResult(); } if (groupByField.size() == 1) { // if only one field then we call to simple groupBy return groupBy(query, groupByField.get(0), featureIdField, options); } else { Bson match = Aggregates.match(query); // add all group-by fields to the projection together with the aggregation field name List<String> groupByFields = new ArrayList<>(groupByField); groupByFields.add(featureIdField); Bson project = Aggregates.project(Projections.include(groupByFields)); // _id document creation to have the multiple id Document id = new Document(); for (String s : groupByField) { id.append(s, "$" + s); } Bson group; if (options.getBoolean("count", false)) { group = Aggregates.group(id, Accumulators.sum("count", 1)); return mongoDBCollection.aggregate(Arrays.asList(match, project, group), options); } else { // Limit the documents passed if count is false Bson limit = Aggregates.limit(options.getInt("limit", 10)); group = Aggregates.group(id, Accumulators.addToSet("features", "$" + featureIdField)); // TODO change the default "_id" returned by mongodb to id return mongoDBCollection.aggregate(Arrays.asList(match, limit, project, group), options); } } }
From source file:org.opencb.cellbase.lib.impl.XRefMongoDBAdaptor.java
License:Apache License
@Override public QueryResult nativeGet(Query query, QueryOptions options) { Bson bson = parseQuery(query);/*ww w . j a v a 2 s.c om*/ Bson match = Aggregates.match(bson); Bson project = Aggregates.project(Projections.include("transcripts.xrefs")); Bson unwind = Aggregates.unwind("$transcripts"); Bson unwind2 = Aggregates.unwind("$transcripts.xrefs"); // This project the three fields of Xref to the top of the object Document document = new Document("id", "$transcripts.xrefs.id"); document.put("dbName", "$transcripts.xrefs.dbName"); document.put("dbDisplayName", "$transcripts.xrefs.dbDisplayName"); Bson project1 = Aggregates.project(document); return mongoDBCollection.aggregate(Arrays.asList(match, project, unwind, unwind2, project1), options); }