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...下载