private void ParseResult(BsonArray resultArray, QupidQuery query, AggregateResult results) { var firstDoc = resultArray.FirstOrDefault(); if (firstDoc == null) return; var collectionSelectProperties = query.SelectProperties.Properties .Where(p => p.Collection.Equals(query.CollectionName, StringComparison.OrdinalIgnoreCase)) .ToList(); results.Columns = collectionSelectProperties.Select(s => !s.IsAggregate? s.Path:s.Alias).ToList(); var shortList = collectionSelectProperties.Select(s => !s.IsAggregate? s.AnalyzedName: s.Alias).ToList(); //TODO: I dont love this because it feels like a double conversion since we convert the _id back to its full name //later - but it is a pretty cheap call if (query.GroupByClause != null) { //change the select property for the group by to _id so it will match mongo results shortList = shortList.Select(s => s.Equals(query.GroupByClause.AggregateByProperty.AnalyzedName) ? "_id" : s).ToList(); } foreach (var curVal in resultArray) { var curDoc = curVal.AsBsonDocument; var row = shortList.Select(col => ExtractColumnValue(curDoc, col)).ToList(); results.Rows.Add(row); } }
public AggregateResult Run(QupidQuery query, MongoDatabase db) { var aggResult = new AggregateResult(); string queryText = null; try { queryText = query.GetMongoQuery(); } catch (Exception e) { _errorManager.AddError(e.Message); } CommandDocument doc; try { doc = new CommandDocument(BsonDocument.Parse(queryText)); } catch (Exception e) { _errorManager.AddError("Error parsing document. " + e.Message); return aggResult; } try { var result = db.RunCommand(doc); if (!result.Ok) { _errorManager.AddError("Error running mongo command."); return aggResult; } var resultArray = result.Response["result"].AsBsonArray; ParseResult(resultArray, query, aggResult); } catch (MongoCommandException mce) { _errorManager.AddError("Error running mongo command. " + mce.Message); return aggResult; } //if a group by - attempt to change the _id back to the group long name //note: this needs to be run before plugins run because if a plugin references the groupby //property it needs to be in full name form if (query.GroupByClause != null && aggResult.Columns.Count > 0) { var idCol = aggResult.Columns.FirstOrDefault(c => c.ToLowerInvariant().Equals("_id")); //the group by id column might already be converted by the runner if subobject if (idCol != null) { var idColIdx = aggResult.Columns.IndexOf(idCol); aggResult.Columns.RemoveAt(idColIdx); aggResult.Columns.Insert(idColIdx, query.GroupByClause.AggregateByProperty.Path); } } if (_joinPlugins != null) { foreach (var plugin in _joinPlugins) { //do column error checking plugin.VerifySelectedColumns(_errorManager); //then run the plugin aggResult = plugin.RunJoin(aggResult); } } //try to convert short names into long names (it will just skip plugin columns since it can't find them) aggResult.Columns = aggResult.Columns.Select(c => query.Collection.ConvertToLongPath(c) ?? c).ToList(); return aggResult; }
public QueryAnalyzer(Compiler compiler, QupidQuery root) { _query = root; _collections = compiler.Collections; _compiler = compiler; }