mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
Clarified relationship between metadata and _facet= facets, updated docs - refs @255
This commit is contained in:
parent
b263da78e3
commit
566f2d31d6
3 changed files with 91 additions and 40 deletions
|
|
@ -104,7 +104,12 @@
|
||||||
<div class="facet-results">
|
<div class="facet-results">
|
||||||
{% for facet_info in sorted_facet_results %}
|
{% for facet_info in sorted_facet_results %}
|
||||||
<div class="facet-info facet-{{ database|to_css_class }}-{{ table|to_css_class }}-{{ facet_info.name|to_css_class }}">
|
<div class="facet-info facet-{{ database|to_css_class }}-{{ table|to_css_class }}-{{ facet_info.name|to_css_class }}">
|
||||||
<p class="facet-info-name"><strong>{{ facet_info.name }}</strong> <a href="{{ path_with_removed_args(request, {'_facet': facet_info['name']}) }}">✖</a></p>
|
<p class="facet-info-name">
|
||||||
|
<strong>{{ facet_info.name }}</strong>
|
||||||
|
{% if facet_hideable(facet_info.name) %}
|
||||||
|
<a href="{{ path_with_removed_args(request, {'_facet': facet_info['name']}) }}">✖</a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
{% for facet_value in facet_info.results %}
|
{% for facet_value in facet_info.results %}
|
||||||
<li><a href="{{ facet_value.toggle_url }}">{{ facet_value.label }}</a> {{ "{:,}".format(facet_value.count) }}</li>
|
<li><a href="{{ facet_value.toggle_url }}">{{ facet_value.label }}</a> {{ "{:,}".format(facet_value.count) }}</li>
|
||||||
|
|
|
||||||
|
|
@ -537,10 +537,12 @@ class TableView(RowTableShared):
|
||||||
|
|
||||||
# facets support
|
# facets support
|
||||||
FACET_SIZE = 20
|
FACET_SIZE = 20
|
||||||
|
metadata_facets = table_metadata.get("facets", [])
|
||||||
|
facets = metadata_facets[:]
|
||||||
try:
|
try:
|
||||||
facets = request.args["_facet"]
|
facets.extend(request.args["_facet"])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
facets = table_metadata.get("facets", [])
|
pass
|
||||||
facet_results = {}
|
facet_results = {}
|
||||||
for column in facets:
|
for column in facets:
|
||||||
facet_sql = """
|
facet_sql = """
|
||||||
|
|
@ -719,6 +721,7 @@ class TableView(RowTableShared):
|
||||||
key=lambda f: (len(f["results"]), f["name"]),
|
key=lambda f: (len(f["results"]), f["name"]),
|
||||||
reverse=True
|
reverse=True
|
||||||
),
|
),
|
||||||
|
"facet_hideable": lambda facet: facet not in metadata_facets,
|
||||||
"is_sortable": any(c["sortable"] for c in display_columns),
|
"is_sortable": any(c["sortable"] for c in display_columns),
|
||||||
"path_with_replaced_args": path_with_replaced_args,
|
"path_with_replaced_args": path_with_replaced_args,
|
||||||
"path_with_removed_args": path_with_removed_args,
|
"path_with_removed_args": path_with_removed_args,
|
||||||
|
|
|
||||||
117
docs/facets.rst
117
docs/facets.rst
|
|
@ -3,8 +3,6 @@
|
||||||
Facets
|
Facets
|
||||||
======
|
======
|
||||||
|
|
||||||
This feature is currently under development, see `#255 <https://github.com/simonw/datasette/issues/255>`_
|
|
||||||
|
|
||||||
Datasette facets can be used to add a faceted browse interface to any Datasette table. With facets, tables are displayed along with a summary showing the most common values in specified columns. These values can be selected to further filter the table.
|
Datasette facets can be used to add a faceted browse interface to any Datasette table. With facets, tables are displayed along with a summary showing the most common values in specified columns. These values can be selected to further filter the table.
|
||||||
|
|
||||||
Facets can be specified in two ways: using queryset parameters, or in ``metadata.json`` configuration for the table.
|
Facets can be specified in two ways: using queryset parameters, or in ``metadata.json`` configuration for the table.
|
||||||
|
|
@ -18,43 +16,72 @@ To turn on faceting for specific columns on a Datasette table view, add one or m
|
||||||
|
|
||||||
This works for both the HTML interface and the ``.json`` view. When enabled, facets will cause a ``facet_results`` block to be added to the JSON output, looking something like this::
|
This works for both the HTML interface and the ``.json`` view. When enabled, facets will cause a ``facet_results`` block to be added to the JSON output, looking something like this::
|
||||||
|
|
||||||
"facet_results": {
|
{
|
||||||
"state": [
|
"state": {
|
||||||
{
|
"name": "state",
|
||||||
"value": "CA",
|
"results": [
|
||||||
"count": 10,
|
{
|
||||||
"selected": false,
|
"value": "CA",
|
||||||
"toggle_url": "http://...&state=CA"
|
"label": "CA",
|
||||||
},
|
"count": 10,
|
||||||
{
|
"toggle_url": "http://...?_facet=city_id&_facet=state&state=CA",
|
||||||
"value": "MI",
|
"selected": false
|
||||||
"count": 4,
|
},
|
||||||
"selected": false,
|
{
|
||||||
"toggle_url": "http://...&state=MI"
|
"value": "MI",
|
||||||
}
|
"label": "MI",
|
||||||
],
|
"count": 4,
|
||||||
"city": [
|
"toggle_url": "http://...?_facet=city_id&_facet=state&state=MI",
|
||||||
{
|
"selected": false
|
||||||
"value": "San Francisco",
|
},
|
||||||
"count": 6,
|
{
|
||||||
"selected": false,
|
"value": "MC",
|
||||||
"toggle_url": "http://...=San+Francisco"
|
"label": "MC",
|
||||||
},
|
"count": 1,
|
||||||
{
|
"toggle_url": "http://...?_facet=city_id&_facet=state&state=MC",
|
||||||
"value": "Detroit",
|
"selected": false
|
||||||
"count": 4,
|
}
|
||||||
"selected": false,
|
],
|
||||||
"toggle_url": "http://...&city=Detroit"
|
"truncated": false
|
||||||
},
|
}
|
||||||
{
|
"city_id": {
|
||||||
"value": "Los Angeles",
|
"name": "city_id",
|
||||||
"count": 4,
|
"results": [
|
||||||
"selected": false,
|
{
|
||||||
"toggle_url": "http://...=Los+Angeles"
|
"value": 1,
|
||||||
}
|
"label": "San Francisco",
|
||||||
]
|
"count": 6,
|
||||||
|
"toggle_url": "http://...?_facet=city_id&_facet=state&city_id=1",
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": 2,
|
||||||
|
"label": "Los Angeles",
|
||||||
|
"count": 4,
|
||||||
|
"toggle_url": "http://...?_facet=city_id&_facet=state&city_id=2",
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": 3,
|
||||||
|
"label": "Detroit",
|
||||||
|
"count": 4,
|
||||||
|
"toggle_url": "http://...?_facet=city_id&_facet=state&city_id=3",
|
||||||
|
"selected": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": 4,
|
||||||
|
"label": "Memnonia",
|
||||||
|
"count": 1,
|
||||||
|
"toggle_url": "http://...?_facet=city_id&_facet=state&city_id=4",
|
||||||
|
"selected": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"truncated": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
If Datasette detects that a column is a foreign key, the ``"label"`` proper will be automatically derived from the detected label column on the referenced table.
|
||||||
|
|
||||||
Facets in metadata.json
|
Facets in metadata.json
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
@ -73,3 +100,19 @@ Here's an example that turns on faceting by default for the ``qLegalStatus`` col
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Facets defined in this way will always be shown in the interface and returned in the API, regardless of the ``_facet`` arguments passed to the view.
|
||||||
|
|
||||||
|
Suggested facets
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Datasette's table UI will suggest facets for the user to apply, based on the following criteria:
|
||||||
|
|
||||||
|
For the currently filtered data are there any columns which, if applied as a facet...
|
||||||
|
|
||||||
|
* Will return 20 or less unique options
|
||||||
|
* Will return more than one unique option
|
||||||
|
* Will return less unique options than the total number of filtered rows
|
||||||
|
* And the query used to evaluate this criteria can be completed in under 20ms
|
||||||
|
|
||||||
|
That last point is particularly important: Datasette runs a query for every column that is displayed on a page, which could get expensive - so to avoid slow load times it sets a time limit of just 20ms for each of those queries. This means suggested facets are unlikely to appear for tables with millions of records in them.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue