Skip to content

Commit

Permalink
Facet results now have "truncated" field
Browse files Browse the repository at this point in the history
 To indicate if there was more than 20 distinct values. Refs #255
  • Loading branch information
simonw committed May 15, 2018
1 parent 590890f commit 158e795
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 95 deletions.
7 changes: 5 additions & 2 deletions datasette/templates/table.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,15 @@ <h3>{% if filtered_table_rows_count or filtered_table_rows_count == 0 %}{{ "{:,}
<p>Suggested facets: {% for facet in suggested_facets %}<a href="{{ facet.toggle_url }}">{{ facet.name }}</a> {% endfor %}
{% endif %}

{% for facet_name, facet_values in facet_results.items() %}
{% for facet_name, facet_info in facet_results.items() %}
<p><strong>{{ facet_name }}</strong></p>
<ul>
{% for facet_value in facet_values %}
{% for facet_value in facet_info.results %}
<li><a href="{{ facet_value.toggle_url }}">{{ facet_value.value }}</a> ({{ facet_value.count }})</li>
{% endfor %}
{% if facet_info.truncated %}
<li>...</li>
{% endif %}
</ul>
{% endfor %}

Expand Down
14 changes: 10 additions & 4 deletions datasette/views/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ async def data(self, request, name, hash, table):
)

# facets support
FACET_SIZE = 20
try:
facets = request.args["_facet"]
except KeyError:
Expand All @@ -499,18 +500,23 @@ async def data(self, request, name, hash, table):
facet_sql = """
select {col} as value, count(*) as count
{from_sql} {and_or_where} {col} is not null
group by {col} order by count desc limit 20
group by {col} order by count desc limit {limit}
""".format(
col=escape_sqlite(column),
from_sql=from_sql,
and_or_where='and' if where_clauses else 'where',
limit=FACET_SIZE+1,
)
try:
facet_rows = await self.execute(
name, facet_sql, params, truncate=False, custom_time_limit=200
)
facet_results[column] = []
for row in facet_rows:
facet_results[column] = {
"name": column,
"results": [],
"truncated": len(facet_rows) > FACET_SIZE,
}
for row in facet_rows[:FACET_SIZE]:
selected = str(other_args.get(column)) == str(row["value"])
if selected:
toggle_path = path_with_removed_args(
Expand All @@ -520,7 +526,7 @@ async def data(self, request, name, hash, table):
toggle_path = path_with_added_args(
request, {column: row["value"]}
)
facet_results[column].append({
facet_results[column]["results"].append({
"value": row["value"],
"count": row["count"],
"toggle_url": urllib.parse.urljoin(
Expand Down
202 changes: 113 additions & 89 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ def test_database_page(app_client):
response = app_client.get('/test_tables.json', gather_request=False)
data = response.json
assert 'test_tables' == data['database']
from pprint import pprint
pprint(data['tables'])
assert [{
'columns': ['content'],
'name': '123_starts_with_digits',
Expand Down Expand Up @@ -893,111 +891,137 @@ def test_page_size_matching_max_returned_rows(app_client_returend_rows_matches_p
(
"/test_tables/facetable.json?_facet=state&_facet=city",
{
"state": [
{
"value": "CA",
"count": 10,
"selected": False,
"toggle_url": "_facet=state&_facet=city&state=CA",
},
{
"value": "MI",
"count": 4,
"selected": False,
"toggle_url": "_facet=state&_facet=city&state=MI",
},
{
"value": "MC",
"count": 1,
"selected": False,
"toggle_url": "_facet=state&_facet=city&state=MC",
},
],
"city": [
{
"value": "San Francisco",
"count": 6,
"selected": False,
"toggle_url": "_facet=state&_facet=city&city=San+Francisco",
},
{
"value": "Detroit",
"count": 4,
"selected": False,
"toggle_url": "_facet=state&_facet=city&city=Detroit",
},
{
"value": "Los Angeles",
"count": 4,
"selected": False,
"toggle_url": "_facet=state&_facet=city&city=Los+Angeles",
},
{
"value": "Memnonia",
"count": 1,
"selected": False,
"toggle_url": "_facet=state&_facet=city&city=Memnonia",
},
],
},
"state": {
"name": "state",
"results": [
{
"value": "CA",
"count": 10,
"toggle_url": "_facet=state&_facet=city&state=CA",
"selected": False,
},
{
"value": "MI",
"count": 4,
"toggle_url": "_facet=state&_facet=city&state=MI",
"selected": False,
},
{
"value": "MC",
"count": 1,
"toggle_url": "_facet=state&_facet=city&state=MC",
"selected": False,
}
],
"truncated": False,
},
"city": {
"name": "city",
"results": [
{
"value": "San Francisco",
"count": 6,
"toggle_url": "_facet=state&_facet=city&city=San+Francisco",
"selected": False,
},
{
"value": "Detroit",
"count": 4,
"toggle_url": "_facet=state&_facet=city&city=Detroit",
"selected": False,
},
{
"value": "Los Angeles",
"count": 4,
"toggle_url": "_facet=state&_facet=city&city=Los+Angeles",
"selected": False,
},
{
"value": "Memnonia",
"count": 1,
"toggle_url": "_facet=state&_facet=city&city=Memnonia",
"selected": False,
}
],
"truncated": False,
}
}
), (
"/test_tables/facetable.json?_facet=state&_facet=city&state=MI",
{
"state": [
{
"value": "MI",
"count": 4,
"selected": True,
"toggle_url": "_facet=state&_facet=city",
},
],
"city": [
{
"value": "Detroit",
"count": 4,
"selected": False,
"toggle_url": "_facet=state&_facet=city&state=MI&city=Detroit",
},
],
"state": {
"name": "state",
"results": [
{
"value": "MI",
"count": 4,
"selected": True,
"toggle_url": "_facet=state&_facet=city",
},
],
"truncated": False,
},
"city": {
"name": "city",
"results": [
{
"value": "Detroit",
"count": 4,
"selected": False,
"toggle_url": "_facet=state&_facet=city&state=MI&city=Detroit",
},
],
"truncated": False,
},
},
), (
"/test_tables/facetable.json?_facet=planet_id",
{
"planet_id": [
{
"value": 1,
"count": 14,
"selected": False,
"toggle_url": "_facet=planet_id&planet_id=1",
},
{
"value": 2,
"count": 1,
"selected": False,
"toggle_url": "_facet=planet_id&planet_id=2",
},
],
"planet_id": {
"name": "planet_id",
"results": [
{
"value": 1,
"count": 14,
"selected": False,
"toggle_url": "_facet=planet_id&planet_id=1",
},
{
"value": 2,
"count": 1,
"selected": False,
"toggle_url": "_facet=planet_id&planet_id=2",
},
],
"truncated": False,
}
},
), (
# planet_id is an integer field:
"/test_tables/facetable.json?_facet=planet_id&planet_id=1",
{
"planet_id": [
{
"value": 1,
"count": 14,
"selected": True,
"toggle_url": "_facet=planet_id",
}
],
"planet_id": {
"name": "planet_id",
"results": [
{
"value": 1,
"count": 14,
"selected": True,
"toggle_url": "_facet=planet_id",
}
],
"truncated": False,
},
},
)
])
def test_facets(app_client, path, expected_facet_results):
response = app_client.get(path, gather_request=False)
facet_results = response.json['facet_results']
# We only compare the querystring portion of the taggle_url
for facet_name, facet_values in facet_results.items():
for facet_value in facet_values:
for facet_name, facet_info in facet_results.items():
assert facet_name == facet_info["name"]
assert False is facet_info["truncated"]
for facet_value in facet_info["results"]:
facet_value['toggle_url'] = facet_value['toggle_url'].split('?')[1]
assert expected_facet_results == facet_results

0 comments on commit 158e795

Please sign in to comment.