Skip to content

Message format: search feature

Daijiro MORI edited this page Jun 24, 2013 · 19 revisions

Request message body

{
  "timeout": 100,
  // msec. If the backend cannot return the result in this timeout limit,
  // both express-droong and droonga can discard any resources
  // about this search request.

  "queries": {
  // a set of queries
  // each of them can reuse the result of another one,
  // as far as they don't contain cycles.

    "mainSearch": {

      "source": "entries",
      // table name, or key name of one of other "queries" values.

      "condition": "name == 'Alice' && age >= 20",
      // a String, an Array, an Object or combination of them.
      //
      // * A String is a groonga expression in script syntax.
      //
      // * An Object is a groonga expression with options, like
      //   {
      //     "query": "foobar",
      //     "matchTo": ["name * 2", "job * 1"], // matchColumns
      //     "defaultOperator": "&&"        // "||", "&&" and "-"
      //     "allowPragma": true    // pragma may not work
      //     "allowColumn": true    // enable column:value style syntax
      //     "matchEscalationThreshold": 10, // not implemented yet
      //   }
      //   or
      //   {
      //     "script": "name == 'Alice' && age >= 20"
      //     "allowUpdate": true // allow updating column values
      //   }
      //
      // * An Array is an expression consisting of an operator
      //   and an arbitrary number of operands, like
      //   ["&&", "name == 'Alice'", "age >= 20"]
      //   The first element is an operator comprising
      //   logical operators, "||", "&&", and "-".

      "sortBy": ["-name", "-age"],
      // an Array or an Object.
      //
      // When it is an Array, each element is a String
      // corresponding with the column name used as a sort key.
      // Each element can be prefixed with a hyphen
      // which means "descending". (default order is "ascending")
      //
      // When it is an Object, "keys" value of it must be an Array
      // which corresponds to the value in the preceding clause.
      // Besides, "offset" and/or "limit" parameters can be assigned
      // which slice the sorted result.

      "groupBy": {"key": "name", "maxNSubRecords": 2},
      // a String or an Object.
      //
      // A String: column name or expression used a the group key.
      //
      // An Object: "key" value is the group key. "maxNSubRecords"
      //            value is an integer number to control the maximum number
      //            of sub-records to be stored in each grouped record.

      "output": {
      // an Object specifying how to output the result of this query.
      // The result is output only when this element is assigned.
      // Otherwise, the result is only calculated and stored
      // probably for reuse in other queries, or for side effects.

        "elements": [
          "startTime",
          "elapsedTime",
          "count",
          "attributes",
          "records"
        ],
        // only the elements assigned in this array will be output.

        "format": "complex",
        // "simple" or "complex". (the default value is "simple")
        // It controls whether "Simple output" or "Complex output" (mentioned later) is used.

        "offset": 10,
        "limit": 100,
        // The result can be sliced here
        // besides that in "sortBy" section.
        "attributes": [
          // basic
          { "label": "realName", "source": "name" },
          // shorthand
          "age", // equals to { label: "age", source: "age" }
          // function call. "source" can include groonga's built-in functions.
          { "label": "html", "source": "snippet_html(name)" },
          // literal
          { "label": "count", "source": "0" },
          { "label": "country", "source": "'Japan'" },
          // sub-record
          { "label": "specimen", "source": "_subrecs",
            "attributes": [
              { "label": "comment", "source": "comment"}
            ]
          }
        ]
      }
    },
    "facetName": {
      "source": "mainSearch",
      "groupBy": "name",
      "sortBy": {
        "keys": ["count"],
        "offset": 0,
        "limit": 100
      },...
    },
    "facetJob": {
      "source": "mainSearch",
      "groupBy": "job",
      "sortBy": {
        "keys": ["count"],
        "offset": 0,
        "limit": 100
      },...
    },
    "facetHour": {
      "source": "mainSearch",
      "groupBy": "dateToHour(date)",
      // not implemented yet
      "sortBy": {
        "keys": ["count"],
        "offset": 0,
        "limit": 100
      },...
    }
  }
}

"scorer", "cache", "queryExpansion", and "queryFlags" are dropped.

Response message body

Simple output (records are presented as simple array)

{
  "mainSearch": { // search results
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 123,
    "attributes": [
      { "name": "name", "type": "ShortText", "vector": false },
      { "name": "age", "type": "UInt32", "vector": false }
    ],
    "records": [ ["a", 10], ["b", 20] ]
  },
  "facetJob": {
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 3,
    "attributes": [
      { "name": "name", "type": "ShortText", "vector": false },
      { "name": "count", "type": "UInt32", "vector": false },
      { "name": "income", "type": "UInt32", "vector": false }
    ],
    "records": [ ["NEET", 10, 0], ["programmer", 9, 100], ["writer", 8, 200] ]
  },
  "facetPrefecture": {
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 3,
    "attributes": [
      { "name": "value", "type": "ShortText", "vector": false },
      { "name": "count", "type": "UInt32", "vector": false }
    ],
    "records": [ ["Tokyo", 10], ["Osaka", 9], ["Hokkaido", 8] ]
  }
}

Complex output (records are presented as an array of hashes)

{
  "mainSearch": { // search results
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 123,
    "attributes": {
      "name": { "type": "ShortText", "vector": false },
      "age": { "type": "UInt32", "vector": false }
    },
    "records": [
      { "name": "a", "age": 10 },
      { "name": "b", "age": 20 }
    ]
  },
  "facetJob": {
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 3,
    "attributes": {
      "name": { "type": "ShortText", "vector": false },
      "count": { "type": "UInt32", "vector": false },
      "income": { "type": "UInt32", "vector": false }
    },
    "records": [
      { "name": "NEET", "count": 10, "income": 0 },
      { "name": "programmer", "count": 9, "income": 100 },
      { "name": "writer", "count": 8, "income": 200 }
    ]
  },
  "facetPrefecture": {
    "startTime": "2001-08-02T10:45:23.5+09:00",
    "elapsedTime": 123.456, // msec, Number type
    "count": 3,
    "attributes": {
      "value": { "type": "ShortText", "vector": false },
      "count": { "type": "UInt32", "vector": false }
    },
    "records": [
      { "value": "Tokyo", "count": 10 },
      { "value": "Osaka", "count": 9 },
      { "value": "Hokkaido", "count: 8 }
    ]
  }
}