[Groonga-commit] groonga/gcs [master] search: use newly written bq translator

Back to archive index

null+****@clear***** null+****@clear*****
2012年 7月 27日 (金) 17:49:10 JST


Kouhei Sutou	2012-07-27 17:49:10 +0900 (Fri, 27 Jul 2012)

  New Revision: a5db243eb9409add833799f63ef835bc51c94afd
  https://github.com/groonga/gcs/commit/a5db243eb9409add833799f63ef835bc51c94afd

  Log:
    search: use newly written bq translator

  Modified files:
    lib/api/2011-02-01/search.js
    lib/bq-translator.js
    test/bq-translator.test.js

  Modified: lib/api/2011-02-01/search.js (+10 -3)
===================================================================
--- lib/api/2011-02-01/search.js    2012-07-27 17:41:14 +0900 (9b7803e)
+++ lib/api/2011-02-01/search.js    2012-07-27 17:49:10 +0900 (9a65f64)
@@ -1,3 +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;
@@ -56,12 +58,14 @@ exports.createHandler = function(context) {
     var domain = new Domain(request, context);
     var query = request.query.q || '';
     var booleanQuery = request.query.bq || '';
+    var filter = null;
 
-    if (!query && booleanQuery) {
+    if (booleanQuery) {
       var translator = new BooleanQueryTranslator();
-      var translatedQuery = translator.translate(booleanQuery);
+      var defaultField = "default_field_fixme"; // FIXME
+      var translatedQuery = translator.translate(booleanQuery, defaultField);
       if (translatedQuery) {
-        query = translatedQuery;
+        filter = translatedQuery;
       } else {
         var body = createErrorBody({
           rid: dummyRid,
@@ -93,6 +97,9 @@ exports.createHandler = function(context) {
     if (domain.isSynonymTableAvailableSync()) {
       options.query_expansion = domain.synonymTableName + '.synonyms';
     }
+    if (filter) {
+      options.filter = filter;
+    }
 
     select(context, options, function(error, data, numFoundRecords) {
       var finishedAt = new Date();

  Modified: lib/bq-translator.js (+31 -29)
===================================================================
--- lib/bq-translator.js    2012-07-27 17:41:14 +0900 (b5b0b3c)
+++ lib/bq-translator.js    2012-07-27 17:49:10 +0900 (8b70261)
@@ -1,12 +1,21 @@
 // -*- indent-tabs-mode: nil; js2-basic-offset: 2 -*-
 /*
-  Translates Boolean Queries used in tinia https://github.com/dlangevin/tinia
-  into groonga query.
+  BooleanQueryTranslator translates Boolean Queries in Amazon
+  CloudSearch into script syntax grn_expr in groonga.
 
-  Not all of Boolean Search Queries are supported.
-  http://docs.amazonwebservices.com/cloudsearch/latest/developerguide/Search.Requests.html#Search.MatchSetExpression
+  Expression Syntax for Boolean Queries:
+    http://docs.amazonwebservices.com/cloudsearch/latest/developerguide/Search.Requests.html#Search.MatchSetExpression
 
-  Returns null if the given query is not supported.
+  Script syntax grn_expr:
+    http://groonga.org/docs/reference/grn_expr/script_syntax.html
+
+  Unsupported syntaxes of Boolean Queries:
+    * range in field value
+    * (filter ...)
+    * (not ...)
+
+  FIXME: Returns null if the given query is not supported.
+         Shuold raise.
 */
 
 
@@ -14,8 +23,22 @@ function BooleanQueryTranslator() {
 }
 
 BooleanQueryTranslator.prototype = {
-  translate: function(query) {
-    return this.translateTinia(query);
+  translate: function(query, defaultField) {
+    var context = {
+      defaultField: defaultField,
+      offset: 0
+    };
+    var expression;
+    if (query[0] == "(") {
+      expression = this.translateGroup(query, context);
+    } else {
+      expression = this.translateExpression(query, context);
+    }
+    if (context.offset != query.length) {
+      // TODO: report error: garbages are exists after expression
+      return "";
+    }
+    return expression;
   },
   skipSpaces: function(query, context) {
     for (; context.offset < query.length; context.offset++) {
@@ -240,27 +263,6 @@ BooleanQueryTranslator.prototype = {
       value += character;
     }
     return field + " == " + value;
-  },
-  translateTinia: function(query) {
-    var matched = null;
-
-    matched = query.match(/^type:'(.+)'$/);
-    if (matched) {
-      return 'type:"' + matched[1] + '"';
-    }
-
-    matched = query.match(/^\(and '([^']+)' type:'(.+)'\)$/);
-    if (matched) {
-      return '"' + matched[1] + '" type:"' + matched[2] + '"';
-    }
-
-    matched = query.match(/^\(and (.+) type:'(.+)'\)$/);
-    if (matched) {
-      return matched[1] + ' type:"' + matched[2] + '"';
-    }
-
-    return null;
-  }
-};
+  }};
 
 exports.BooleanQueryTranslator = BooleanQueryTranslator;

  Modified: test/bq-translator.test.js (+6 -6)
===================================================================
--- test/bq-translator.test.js    2012-07-27 17:41:14 +0900 (700748c)
+++ test/bq-translator.test.js    2012-07-27 17:49:10 +0900 (fba15b2)
@@ -9,7 +9,7 @@ function testQuery(label, expected, query) {
   test('query: ' + label + ': ' +
        '<' + query + '> -> <' + expected + '>', function() {
     var translator = new BooleanQueryTranslator();
-    assert.equal(expected, translator.translate(query));
+    assert.equal(expected, translator.translate(query, "field"));
   });
 }
 
@@ -57,14 +57,14 @@ function testExpression(label, expectedScriptGrnExpr, expectedOffset,
 
 suite('BoolanQueryTranslator', function() {
   testQuery("expression",
-            'type:"ModelName"',
+            'type @ "ModelName"',
             "type:'ModelName'");
   testQuery("group: raw expressions",
-            'query query type:"ModelName"',
-            "(and query query type:'ModelName')");
+            '(field1 @ "keyword1" && field2 @ "keyword2" && type @ "ModelName")',
+            "(and field1:'keyword1' field2:'keyword2' type:'ModelName')");
   testQuery("group: quoted expression",
-            '"query query" type:"ModelName"',
-            "(and 'query query' type:'ModelName')");
+            '(field @ "keyword1" && field @ "keyword2" && type @ "ModelName")',
+            "(and 'keyword1 keyword2' type:'ModelName')");
 
   testGroup("field",
             "field1 @ \"keyword1\"",
-------------- next part --------------
HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B...
下载 



Groonga-commit メーリングリストの案内
Back to archive index