[Groonga-commit] groonga/gcs [master] Split SelectQuery implementation

Back to archive index

YUKI Hiroshi null+****@clear*****
Fri Aug 24 19:57:54 JST 2012


YUKI Hiroshi	2012-08-24 19:57:54 +0900 (Fri, 24 Aug 2012)

  New Revision: 2b2b8b73adc71aa9ca75bb78efcdf71328b9a9de
  https://github.com/groonga/gcs/commit/2b2b8b73adc71aa9ca75bb78efcdf71328b9a9de

  Log:
    Split SelectQuery implementation

  Added files:
    lib/select-query.js
  Modified files:
    lib/api/2011-02-01/search.js

  Modified: lib/api/2011-02-01/search.js (+0 -117)
===================================================================
--- lib/api/2011-02-01/search.js    2012-08-24 19:24:55 +0900 (ee38d50)
+++ lib/api/2011-02-01/search.js    2012-08-24 19:57:54 +0900 (e0c7356)
@@ -1,9 +1,5 @@
 // -*- indent-tabs-mode: nil; js2-basic-offset: 2 -*-
 
-var Domain = require('../../database').Domain;
-var nroonga = require('../../wrapped-nroonga');
-var BooleanQueryTranslator = require('../../bq-translator').BooleanQueryTranslator;
-
 var dummyRid = '000000000000000000000000000000000000000000000000000000000000000';
 
 function formatFacets(data) {
@@ -123,119 +119,6 @@ function createErrorBody(options) {
   };
 }
 
-function translateQueryToBooleanQuery(query) {
-  return "'" + query.replace(/(['\\])/g, '\\$1') + "'";
-}
-
-function SelectQuery(request, context) {
-  var domain = new Domain(request, context);
-  var query = request.query.q || '';
-  var booleanQuery = request.query.bq || '';
-  var filters = [];
-  var matchExpression = '';
-  var facets = request.query.facet;
-  var noResult = false;
-
-  var defaultFields;
-  var defaultField = domain.defaultSearchField;
-  if (defaultField)
-    defaultFields = [defaultField];
-  else
-    defaultFields = domain.searchableIndexFields.filter(function(field) {
-      return field.type == 'text';
-    });
-
-  var defaultFieldNames = defaultFields.map(function(field) {
-    return field.name;
-  });
-
-  if (query) {
-    var queryAsBooleanQuery = translateQueryToBooleanQuery(query);
-    var translator = new BooleanQueryTranslator(queryAsBooleanQuery);
-    translator.domain = domain;
-    translator.defaultFieldNames = defaultFieldNames;
-    try {
-      filters.push(translator.translate());
-    } catch (error) {
-      error.queryType = 'q';
-      throw error;
-    }
-    matchExpression = '(label ' + queryAsBooleanQuery + ')';
-  }
-
-  if (booleanQuery) {
-    var translator = new BooleanQueryTranslator(booleanQuery);
-    translator.domain = domain;
-    translator.defaultFieldNames = defaultFieldNames;
-    try {
-      filters.push(translator.translate());
-    } catch (error) {
-      error.queryType = 'bq';
-      throw error;
-    }
-    noResult = noResult || !translator.available;
-    if (matchExpression.length > 0) {
-      matchExpression = '(and ' + matchExpression + ' ' + booleanQuery + ')';
-    } else {
-      matchExpression = booleanQuery;
-    }
-  }
-
-  filters = filters.map(function(filter) {
-    return '(' + filter + ')';
-  });
-  var size = parseInt(request.query.size || '10', 10);
-  var start = parseInt(request.query.start || '0', 10);
-  var filter = filters.join(' && ');
-  var requestedOutputColumns = request.query['return-fields'] || '';
-  requestedOutputColumns = requestedOutputColumns.split(/\s*,\s*/);
-  var outputColumns = domain.resultReturnableIndexFields
-                            .filter(function(field) {
-                              return requestedOutputColumns.indexOf(field.name) > -1;
-                            })
-                            .map(function(field) {
-                              return field.columnName;
-                            });
-  outputColumns.unshift('_key');
-  var options = {
-    table:          domain.tableName,
-    filter:         filter,
-    limit:          size,
-    offset:         start,
-    output_columns: outputColumns.join(', ')
-  };
-
-  if (domain.hasSynonymsTableSync()) {
-    options.query_expansion = domain.synonymsTableName + '.synonyms';
-  }
-  if (filter) {
-    options.filter = filter;
-  }
-
-  if (facets) {
-    var facetReturnableFields = domain.facetReturnableIndexFields
-                                  .map(function(field) {
-                                    return field.name;
-                                  });
-    facets = facets.split(/\s*,\s*/)
-               .filter(function(field) {
-                 return facetReturnableFields.indexOf(field) > -1;
-               });
-    options.drilldown = facets.join(',');
-    options.drilldown_sortby = '-_nsubrecs';
-    // TODO support sorting parameter
-    // TODO support facet-FIELD-top-n parameter
-  }
-
-  return {
-    selectOptions:   options,
-    matchExpression: matchExpression,
-    start:           start,
-    facets:          facets,
-    noResult:        noResult
-  };
-}
-
 exports.createHandler = function(context) {
   return function(request, response) {
     var startedAt = new Date();

  Added: lib/select-query.js (+204 -0) 100644
===================================================================
--- /dev/null
+++ lib/select-query.js    2012-08-24 19:57:54 +0900 (74abbef)
@@ -0,0 +1,204 @@
+var Domain = require('./database').Domain;
+var BooleanQueryTranslator = require('./bq-translator').BooleanQueryTranslator;
+
+function translateQueryToBooleanQuery(query) {
+  return "'" + query.replace(/(['\\])/g, '\\$1') + "'";
+}
+
+// this should be re-implemented as a class
+function SelectQuery(request, context) {
+  this.request = request;
+  this.domain = new Domain(request, context);
+
+  this.filters         = [];
+  this.matchExpression = '';
+  this.noResult        = false;
+
+  this.parse();
+}
+
+SelectQuery.prototype = {
+  get query() {
+    return this.request.query.q || '';
+  },
+
+  get booleanQuery() {
+    return this.request.query.bq || '';
+  },
+
+  get size() {
+    if (this._size === undefined)
+      this._size = this.prepareSize();
+    return this._size;
+  },
+  prepareSize: function() {
+    return parseInt(this.request.query.size || '10', 10);
+  },
+
+  get start() {
+    if (this._start === undefined)
+      this._start = this.prepareStart();
+    return this._start;
+  },
+  prepareStart: function() {
+    return parseInt(this.request.query.start || '0', 10);
+  },
+
+  get returnFields() {
+    if (this._returnFields === undefined)
+      this._returnFields = this.prepareReturnFields();
+    return this._returnFields;
+  },
+  prepareReturnFields: function() {
+    var fields = this.request.query['return-fields'];
+    if (fields)
+      return fields.split(/\s*,\s*/);
+    else
+      return [];
+  },
+
+  get facets() {
+    if (this._facets === undefined)
+      this._facets = this.prepareFacets();
+    return this._facets;
+  },
+  prepareFacets: function() {
+    var facets = this.request.query.facet;
+    if (facets)
+      return facets.split(/\s*,\s*/);
+    else
+      return [];
+  },
+
+  get defaultFieldNames() {
+    if (this._defaultFieldNames === undefined)
+      this._defaultFieldNames = this.prepareDefaultFieldNames();
+    return this._defaultFieldNames;
+  },
+  prepareDefaultFieldNames: function() {
+    var defaultFields;
+    var defaultField = this.domain.defaultSearchField;
+    if (defaultField)
+      defaultFields = [defaultField];
+    else
+      defaultFields = this.domain.searchableIndexFields.filter(function(field) {
+        return field.type == 'text';
+      });
+
+    var defaultFieldNames = defaultFields.map(function(field) {
+      return field.name;
+    });
+  },
+
+  parse: function() {
+    var filters = [];
+    var matchExpression = '';
+
+    if (this.query) {
+      var queryAsBooleanQuery = translateQueryToBooleanQuery(this.query);
+      var translator = new BooleanQueryTranslator(queryAsBooleanQuery);
+      translator.domain = this.domain;
+      translator.defaultFieldNames = this.defaultFieldNames;
+      try {
+        filters.push(translator.translate());
+      } catch (error) {
+        error.queryType = 'q';
+        throw error;
+      }
+      matchExpression = '(label ' + queryAsBooleanQuery + ')';
+    }
+
+    if (this.booleanQuery) {
+      var translator = new BooleanQueryTranslator(this.booleanQuery);
+      translator.domain = this.domain;
+      translator.defaultFieldNames = this.defaultFieldNames;
+      try {
+        filters.push(translator.translate());
+      } catch (error) {
+        error.queryType = 'bq';
+        throw error;
+      }
+      this.noResult = !translator.available;
+      if (matchExpression.length > 0) {
+        matchExpression = '(and ' + matchExpression + ' ' + this.booleanQuery + ')';
+      } else {
+        matchExpression = this.booleanQuery;
+      }
+    }
+
+    this.filters = filters.map(function(filter) {
+      return '(' + filter + ')';
+    });
+    this.matchExpression = matchExpression;
+  },
+
+  // for groonga query
+  get filter() {
+    return this.filters.join(' && ');
+  },
+
+  get drilldownColumns() {
+    if (this._drilldownColumns === undefined)
+      this._drilldownColumns = this.prepareDrilldownColumns();
+    return this._drilldownColumns;
+  },
+  prepareDrilldownColumns: function() {
+    var facetReturnableFields = this.domain.facetReturnableIndexFields
+                                  .map(function(field) {
+                                    return field.name;
+                                  });
+    return this.facets
+      .filter(function(field) {
+        return facetReturnableFields.indexOf(field) > -1;
+      })
+      .map(function(field) {
+        return this.domain.getIndexField(field).columnName;
+      }, this);
+  },
+
+  get outputColumns() {
+    if (this._outputColumns === undefined)
+      this._outputColumns = this.prepareOutputColumns();
+    return this._outputColumns;
+  },
+  prepareOutputColumns: function() {
+    var returnFields = this.returnFields;
+    var columns = this.domain.resultReturnableIndexFields
+                    .filter(function(field) {
+                      return returnFields.indexOf(field.name) > -1;
+                    })
+                    .map(function(field) {
+                      return field.columnName;
+                    });
+    columns.unshift('_key');
+    return columns;
+  },
+
+  get selectOptions() {
+    if (this._selectOptions === undefined)
+      this._selectOptions = this.prepareSelectOptions();
+    return this._selectOptions;
+  },
+  prepareSelectOptions: function() {
+    var options = {
+      table:          this.domain.tableName,
+      filter:         this.filter,
+      limit:          this.size,
+      offset:         this.start,
+      output_columns: this.outputColumns.join(', ')
+    };
+
+    if (this.domain.hasSynonymsTableSync())
+      options.query_expansion = this.domain.synonymsTableName + '.synonyms';
+
+    if (this.facets.length) {
+      options.drilldown = this.drilldownColumns.join(',');
+      options.drilldown_sortby = '-_nsubrecs';
+      // TODO support sorting parameter
+      // TODO support facet-FIELD-top-n parameter
+    }
+    return options;
+  }
+};
+
+exports.SelectQuery = SelectQuery;
-------------- next part --------------
HTML����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index