|
@@ -16,7 +16,7 @@ var DocumentSource = require('./documentSources/DocumentSource'),
|
|
|
CursorDocumentSource = require('./documentSources/CursorDocumentSource'),
|
|
CursorDocumentSource = require('./documentSources/CursorDocumentSource'),
|
|
|
SortDocumentSource = require('./documentSources/SortDocumentSource'),
|
|
SortDocumentSource = require('./documentSources/SortDocumentSource'),
|
|
|
MatchDocumentSource = require('./documentSources/MatchDocumentSource'),
|
|
MatchDocumentSource = require('./documentSources/MatchDocumentSource'),
|
|
|
- Cursor = require('../query/ArrayRunner');
|
|
|
|
|
|
|
+ getRunner = require('../query').getRunner;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Create a Cursor wrapped in a DocumentSourceCursor, which is suitable to be the first source for a pipeline to begin with.
|
|
* Create a Cursor wrapped in a DocumentSourceCursor, which is suitable to be the first source for a pipeline to begin with.
|
|
@@ -37,9 +37,6 @@ var DocumentSource = require('./documentSources/DocumentSource'),
|
|
|
**/
|
|
**/
|
|
|
klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
|
|
klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
|
|
|
|
|
|
|
|
- // get the full "namespace" name
|
|
|
|
|
- var data = expCtx.ns; //NOTE: ns will likely be either an array of documents or a document source in munge
|
|
|
|
|
-
|
|
|
|
|
// We will be modifying the source vector as we go
|
|
// We will be modifying the source vector as we go
|
|
|
var sources = pipeline.sources;
|
|
var sources = pipeline.sources;
|
|
|
|
|
|
|
@@ -68,20 +65,20 @@ klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
|
|
|
var projectionForQuery = deps.needTextScore ? deps.toProjection() : {};
|
|
var projectionForQuery = deps.needTextScore ? deps.toProjection() : {};
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
- Look for an initial sort; we'll try to add this to the
|
|
|
|
|
- Cursor we create. If we're successful in doing that (further down),
|
|
|
|
|
- we'll remove the $sort from the pipeline, because the documents
|
|
|
|
|
- will already come sorted in the specified order as a result of the
|
|
|
|
|
- index scan.
|
|
|
|
|
|
|
+ Look for an initial sort; we'll try to add this to the
|
|
|
|
|
+ Cursor we create. If we're successful in doing that (further down),
|
|
|
|
|
+ we'll remove the $sort from the pipeline, because the documents
|
|
|
|
|
+ will already come sorted in the specified order as a result of the
|
|
|
|
|
+ index scan.
|
|
|
*/
|
|
*/
|
|
|
- var sortStorage,
|
|
|
|
|
|
|
+ var sortStage,
|
|
|
sortObj,
|
|
sortObj,
|
|
|
sortInRunner = false;
|
|
sortInRunner = false;
|
|
|
if (sources.length) {
|
|
if (sources.length) {
|
|
|
sortStage = sources[0] instanceof SortDocumentSource ? sources[0] : undefined;
|
|
sortStage = sources[0] instanceof SortDocumentSource ? sources[0] : undefined;
|
|
|
|
|
|
|
|
//need to check the next source since we are not deleting the initial match in munge
|
|
//need to check the next source since we are not deleting the initial match in munge
|
|
|
- if (!sortStorage && sources[0] instanceof MatchDocumentSource){
|
|
|
|
|
|
|
+ if (!sortStage && sources[0] instanceof MatchDocumentSource){
|
|
|
sortStage = sources[1] instanceof SortDocumentSource ? sources[1] : undefined;
|
|
sortStage = sources[1] instanceof SortDocumentSource ? sources[1] : undefined;
|
|
|
}
|
|
}
|
|
|
if (sortStage) {
|
|
if (sortStage) {
|
|
@@ -92,23 +89,15 @@ klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Create the Runner.
|
|
// Create the Runner.
|
|
|
- // NOTE: the logic here is munge specific
|
|
|
|
|
- var runner;
|
|
|
|
|
- if (data.constructor === Array) {
|
|
|
|
|
- runner = new ArrayRunner(data);
|
|
|
|
|
- } else if (data instanceof DocumentSource) {
|
|
|
|
|
- //do something else here. TODO: make a new Runner Type?
|
|
|
|
|
- } else {
|
|
|
|
|
- throw new Error('unrecognized data source');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // NOTE: the logic here is simplified for munge
|
|
|
|
|
+ var runner = getRunner(expCtx.ns, queryObj, sortObj, projectionForQuery, sources);
|
|
|
|
|
|
|
|
// DocumentSourceCursor expects a yielding Runner that has had its state saved.
|
|
// DocumentSourceCursor expects a yielding Runner that has had its state saved.
|
|
|
- //runner->setYieldPolicy(Runner::YIELD_AUTO);
|
|
|
|
|
|
|
+ //runner.setYieldPolicy(Runner.RunnerState.YIELD_AUTO); //Skipped as we don't really support yielding yet
|
|
|
runner.saveState();
|
|
runner.saveState();
|
|
|
|
|
|
|
|
// Put the Runner into a DocumentSourceCursor and add it to the front of the pipeline.
|
|
// Put the Runner into a DocumentSourceCursor and add it to the front of the pipeline.
|
|
|
- var source = new DocumentSourceCursor("", runner, pExpCtx);
|
|
|
|
|
|
|
+ var source = new CursorDocumentSource("", runner, expCtx);
|
|
|
|
|
|
|
|
// Note the query, sort, and projection for explain.
|
|
// Note the query, sort, and projection for explain.
|
|
|
source.setQuery(queryObj);
|
|
source.setQuery(queryObj);
|
|
@@ -124,74 +113,4 @@ klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
|
|
|
pipeline.addInitialSource(source);
|
|
pipeline.addInitialSource(source);
|
|
|
|
|
|
|
|
return runner;
|
|
return runner;
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- var sources = pipeline.sources;
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: SKIPPED: look for initial match
|
|
|
|
|
- // NOTE: SKIPPED: create a query object
|
|
|
|
|
-
|
|
|
|
|
- // Look for an initial simple project; we'll avoid constructing Values for fields that won't make it through the projection
|
|
|
|
|
- var projection = {};
|
|
|
|
|
- var dependencies;
|
|
|
|
|
- var deps = {};
|
|
|
|
|
- var status = DocumentSource.GetDepsReturn.SEE_NEXT;
|
|
|
|
|
- for (var i=0; i < sources.length && status !== DocumentSource.GetDepsReturn.EXHAUSTIVE; i++) {
|
|
|
|
|
- status = sources[i].getDependencies(deps);
|
|
|
|
|
- if(Object.keys(deps).length === 0) {
|
|
|
|
|
- status = DocumentSource.GetDepsReturn.NOT_SUPPORTED;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (status === DocumentSource.GetDepsReturn.EXHAUSTIVE) {
|
|
|
|
|
- projection = DocumentSource.depsToProjection(deps);
|
|
|
|
|
- dependencies = DocumentSource.parseDeps(deps);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: SKIPPED: Look for an initial sort
|
|
|
|
|
- // NOTE: SKIPPED: Create the sort object
|
|
|
|
|
-
|
|
|
|
|
- //get the full "namespace" name
|
|
|
|
|
- // var fullName = dbName + "." + pipeline.collectionName;
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: SKIPPED: if(DEV) log messages
|
|
|
|
|
-
|
|
|
|
|
- // Create the necessary context to use a Cursor
|
|
|
|
|
- // NOTE: SKIPPED: pSortedCursor bit
|
|
|
|
|
- // NOTE: SKIPPED: pUnsortedCursor bit
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: Deviating from mongo here. We're passing in a source or set of documents instead of collection name in the ctx.ns field
|
|
|
|
|
- var source;
|
|
|
|
|
- if(expCtx.ns instanceof DocumentSource){
|
|
|
|
|
- source = expCtx.ns;
|
|
|
|
|
- } else {
|
|
|
|
|
- var cursorWithContext = new CursorDocumentSource.CursorWithContext(/*fullName*/);
|
|
|
|
|
-
|
|
|
|
|
- // Now add the Cursor to cursorWithContext
|
|
|
|
|
- cursorWithContext._cursor = new Cursor( expCtx.ns ); //NOTE: collectionName will likely be an array of documents in munge
|
|
|
|
|
-
|
|
|
|
|
- // wrap the cursor with a DocumentSource and return that
|
|
|
|
|
- source = new CursorDocumentSource( cursorWithContext, expCtx );
|
|
|
|
|
-
|
|
|
|
|
- // NOTE: SKIPPED: Note the query and sort
|
|
|
|
|
-
|
|
|
|
|
- if (Object.keys(projection).length) source.setProjection(projection, dependencies);
|
|
|
|
|
-
|
|
|
|
|
- while(sources.length > 0 && source.coalesce(sources[0])) { //Note: Attempting to coalesce into the cursor source
|
|
|
|
|
- sources.shift();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- pipeline.addInitialSource(source);
|
|
|
|
|
};
|
|
};
|