Property filters

Data for filter UI

This needs more documentation…

Issue a GET request to categories/{id}/filters to get information about all the properties available in that category. Metadata about the properties is also provided, e.g. how many products have a specific value. This information and metadata can be used to create a user interface to allow end users to filter the products (see Creating a filter).

{
  "meta":
  {
    "property_definitions":
    [
      {
        "item_type": "category",
        "name": "General",
        "children":
        [
          {
            "item_type": "property",
            "id": "1022",
            "name": "Genre",
            "unit": null,
            "description": null,
            "type": "list-and",
            "has_icon": false,
            "children": null
          }
        ]
      }
    ]
  },
  "item":
  {
    "1022":
    {
      "values":
      [
        {
           "name": "Sandbox",
           "id": 10324,
           "products": 3
        },
        {
           "name": "Action",
           "id": 1023,
           "products": 3460
        }
      ],
      "max": 3460
    }
  }
}

Hierarchical information

Filter information is hierarchical (unless you specify exactly what ids you want). You should follow children.

Properties with icons

A property can have an associated icon (e.g. light socket types). If this is the case the property metadata has_icon will be set to true and each of its values will have an icon_uri.

Since it’s assumed that if has_icon is true that all of the property values have an associated icon, the icon_uri might lead to a 404 not found.

Creating a filter

Issue a POST request to categories/{id}/filters to create a filter. The request body should contain the constraints you want. An example is:

{
    "7151": {"from": 30, "to": "80"},
    "197": {"from": 2007, "to": null},
    "443": {
        "from": {"from": 0, "to": 50},
        "to": {"from": 60, "to": null}
    },
    "price": {"from": null, "to": 15000},
    "name": "Nikkor",
    "brands": [31,1249,16104],
    "3495": [3496,3497],
    "in_stock": true
}

The general syntax is "property id": "constraints", where constraints have different formats depending on the property type.

Here’s some abbreviated data from GET categories/326/filters/7151,197,443,price,name,brands,in_stock,3495

{
  "meta": {
    "property_definitions": [
      "Comment: all definitions also have item_type, unit, description and
      children, but I've removed them in this example.",
      {
        "id": "7151",
        "name": "Diameter",
        "type": "decimal"
      },
      {
        "id": "197",
        "name": "Release year",
        "type": "date-year"
      },
      {
        "id": "443",
        "name": "Focal length (physical)",
        "type": "interval-span"
      },
      {
        "id": "price",
        "name": "Price",
        "type": "decimal"
      },
      {
        "id": "name",
        "name": "Product name",
        "type": "string"
      },
      {
        "id": "brands",
        "name": "Brand",
        "type": "list-or"
      },
      {
        "id": "in_stock",
        "name": "In stock?",
        "type": "boolean"
      },
      {
        "id": "3495",
        "name": "Type of lens",
        "type": "list-and"
      }
    ]
  },
  "item": {
    "7151": {
      "values": [
        {"from": 40, "to": 60, "products": 6},
        {"from": 60, "to": 80, "products": 120},
        "more rows..."
        {"from": 220, "to": 240, "products": 0}
      ],
      "min": 41,
      "max": 236.5
    },
    "197": {
      "values": [
        {"from": 1987, "to": 1988, "products": 4},
        "more rows...",
        {"from": 2013, "to": 2014, "products": 41}
      ],
      "min": 1987,
      "max": 2013
    },
    "443": {
      "values": {
        "from": [
          {
            "from": 0, "to": 80, "products": 695},
          "more rows..."
        ],
        "to": [
          {"from": 0, "to": 100, "products": 586},
          "more rows..."
        ]
      },
      "min": 3.2,
      "max": 1300
    },
    "price": {
      "values": [
        {"from": 250, "to": 300, "products": 2},
        "more rows...",
        {"from": 150000, "to": 192875, "products": 15}
      ],
      "min": 229,
      "max": 192875
    },
    "name": {
      "values": [
        null
      ]
    },
    "brands": {
      "min": null,
      "max": 329,
      "values": [
        {"id": 31, "products": 100, "name": "Nikon"},
        {"id": 1249, "products": 30,"name": "Tokina"},
        {"id": 16104, "products": 27, "name": "Voigtländer"},
        "more rows..."
      ]
    },
    "in_stock": {
      "values": {
        "false": 0,
        "true": 0
      },
      "min": 0,
      "max": 0
    },
    "3495": {
      "values": [
        {"name": "Tele", "id": 3496, "products": 396},
        {"name": "Wide angle", "id": 3497, "products": 438},
        "more rows..."
      ],
      "max": 438
    }
  }
}

We have a couple of different property types, each with it’s own format.

boolean

Example: ‘in_stock’

The simplest one. Just pass boolean true or false, they work as expected.

"in_stock": true

Finds products available in stock at any store.

decimal / integer

Example: ‘7151’ (Diameter) and ‘price’

A numeric value. When filtering on these, you must supply both from and to. If you want to omit one of them, set the value to null.

"7151": {"from": 30, "to": 80}

Find products with a diameter between 30 and 80 (exactly 30 or 80 are included)

"7151": {"from": null, "to": 80}

Find products with a diameter lower than or equal to 80

"7151": {"from": 30, "to": null}

Find products with a diameter above or equal to 30

date-year

Example: ‘197’ (Release year)

A year. It works the same way as decimal / integer, with one difference; it should not be used with number formatting to add thousands separator etc.

string

Example: ‘name’

The constraint is a string, which has to be a part of the property to match.

"name": "Nikkor"

Find products with “Nikkor” in their name.

list-and

Example: ‘3495’ (Type of lens)

"3495": [3496,3497]

Find products having Tele (3496) and Wide angle (3497) lens.

A product can have 0 or many of these values.

list-or

Example: ‘brands’

"brands": [31,1249,16104]

Find products from Nikon (31), Tokina (1249) or Voigtländer (16104).

A product can only have one of these values.

list-tree-or

The example structure above doesn’t include a list-tree-or, but here’s a small example of how they look:

{
  "meta": {
    "property_definitions": [
      {
        "id": "1124",
        "name": "Graphics processor",
        "type": "list-tree-or"
      }
    ]
  },
  "item": {
    "1124": {
      "min": null,
      "max": 959,
      "values": [
        {
          "id": "GeForce",
          "name": "GeForce",
          "products": 594,
          "children": [
            {
              "id": "GeForce GT",
              "name": "GeForce GT",
              "products": 424,
              "children": [
                {"id": 24705, "products": 48, "name": "GT 750M"},
                {"id": 24562, "products": 56, "name": "GT 740M"}
              ]
            },
            {
              "id": 13470,
              "products": 6,
              "name": "GeForce 310M"
            },
            {
              "id": "GeForce GTX",
              "name": "GeForce GTX",
              "products": 109,
              "children": [
                {"id": 15677, "products": 1, "name": "GTX 285M"},
                {"id": 16845, "products": 2, "name": "GTX 560M"}
              ]
            }
          ]
        }
      ]
    }
  }
}

When creating filters, it works the same way as list-or, but not all array members have to be integers. Everything returned as id can be sent as a filter.An example:

"1124": ["GeForce GT", 13470]

Finds all products with a GeForce 310M (13470) or any “GeForce GT” (“GeForce GT 750M”, “GeForce GT 740M”, and any others).

interval-span / interval-contain / interval-touch

Example: ‘443’ (Focal length) - which is ‘interval-span’

Interval properties can be a bit tricky to understand.

We support a couple of different types of intervals.

span

Find products where the product’s interval span the entire filter interval.

An example is “Find a loudspeaker with a frequency range of at least 20 - 20000 Hz”.

contain

Find products where the product’s entire interval fits inside the filter interval.

An example is “Find a boardgame with playing time between 1 and 2 hours”, or “Find a vacuum cleaner with a maximum noise level of 50 dB”.

touch

Find products where the product’s interval touches the filter interval, it does not have to overlap entirely.

An example is “Find a toy suitable for a kid between 8 and 10 years old”.

All the types use the same syntax. They have the same structure as decimal / integer, but from and to are not numbers, but objects with numbers. An example shows this best

"443": {
  "from": {"from": 0, "to": 50},
  "to": {"from": 60, "to": null}
}

This finds products with a focal length (443) of at least 50 to 60.

A product with 40 – 70 is okay, a product with 45 – 120 is not (it doesn’t match from).