Build Your Own Dataset¶
Overview¶
This guide walks you through building a custom dataset end-to-end. We will use a bookmark manager as the example — a collection of saved URLs with titles, tags, and descriptions. The same steps apply to any dataset.
By the end you will have a working Alfred workflow that full-text searches your bookmarks and opens the selected URL in the browser.
Step 1 — Design Your Data Schema¶
Before writing any files, decide what fields your records will have and how each one should behave in search.
Ask yourself:
Which fields do users search against? → these need an indexed type (
ngram,text,keyword)Which fields are used only in the display or as the action argument? → use
storedIs there a numeric field to sort by (date, score, priority)? → use
numericwithindexedandfastWhat should pressing
Enterdo — open a URL or open a file? → that field goes inarg_field
For our bookmarks example:
Field |
Type |
Reason |
|---|---|---|
|
|
Partial-word search; users type incomplete titles |
|
|
Used as |
|
|
Full-word search; tags are complete words |
|
|
Full-word phrase search on prose |
|
|
Unix timestamp, sortable newest-first |
Step 2 — Create the Dataset Directory¶
Choose a short, lowercase name with no spaces (hyphens are fine).
We will use bookmarks.
mkdir -p ~/.alfred-afwf/afwf_fts_anything/bookmarks/icons
Step 3 — Write the Data File¶
Create ~/.alfred-afwf/afwf_fts_anything/bookmarks/bookmarks-data.json
as a JSON array. Each object must have the same keys you plan to declare in
the setting file:
[
{
"title": "Hacker News",
"url": "https://news.ycombinator.com",
"tags": "tech news programming",
"description": "Social news website focusing on computer science and entrepreneurship.",
"added_at": 1700000000
},
{
"title": "Real Python",
"url": "https://realpython.com",
"tags": "python tutorial learning",
"description": "Python tutorials for developers of all skill levels.",
"added_at": 1710000000
},
{
"title": "Excalidraw",
"url": "https://excalidraw.com",
"tags": "design diagram tool",
"description": "Virtual whiteboard for sketching hand-drawn like diagrams.",
"added_at": 1720000000
}
]
Tips:
Every record should have the same keys. Missing keys are treated as empty.
Values must match the declared field type: a
numericfield must contain a number, not a string.The file can contain thousands of records — the index is built once and queries remain fast regardless of dataset size.
Step 4 — Write the Setting File¶
Create ~/.alfred-afwf/afwf_fts_anything/bookmarks/bookmarks-setting.json:
{
"fields": [
// partial-word title search, weighted highest
{"type": "ngram", "name": "title", "min_gram": 2, "max_gram": 10, "boost": 2.0},
// stored only — used as action arg and in title template
{"type": "stored", "name": "url"},
// full-word search on tags and description
{"type": "text", "name": "tags", "boost": 1.5},
{"type": "text", "name": "description"},
// unix timestamp, sortable newest-first
{"type": "numeric", "name": "added_at", "kind": "i64", "indexed": true, "fast": true}
],
"sort": [
{"name": "added_at", "descending": true}
],
"title_field": "{title}",
"subtitle_field": "{tags} | {description}",
"arg_field": "{url}",
"autocomplete_field": "{title}",
"icon_field": "bookmark.png"
}
Refer to Setting File & Data File for the full field type reference.
Step 5 — Add an Icon (Optional)¶
Place a PNG icon at:
~/.alfred-afwf/afwf_fts_anything/bookmarks/icons/bookmark.png
If the file does not exist, Alfred uses the workflow’s default icon. Any 256×256 or 512×512 PNG works well.
Step 6 — Create the Alfred Script Filter¶
In Alfred Preferences → Workflows, add a Script Filter with:
Language:
/bin/bashArgument:
OptionalKeyword:
bm(or any trigger you prefer)Script:
~/.local/bin/uvx --from "afwf-fts-anything==2.0.2" afwf-fts-anything fts \ --dataset-name 'bookmarks' \ --query '{query}' \ --action open_url
Wire the Script Filter to an Open URL action. See Alfred Workflow Setup for detailed wiring instructions.
Step 7 — Build the Index and Test¶
Open Alfred and type your keyword:
bm python
The first query builds the index (takes one to two seconds). You should see Real Python appear. Subsequent queries are instant.
Try:
bm design → matches Excalidraw via tags
bm news → matches Hacker News
bm → all bookmarks, newest first
bm ? → reveals bookmarks-setting.json in Finder
Step 8 — Iterate¶
Datasets rarely come out perfect on the first try. A typical iteration cycle:
Edit
bookmarks-data.json(add records, fix values).Rebuild the index:
~/.local/bin/uvx --from "afwf-fts-anything==2.0.2" afwf-fts-anything rebuild-index \ --dataset-name 'bookmarks'
Test in Alfred.
If results are not what you expect, tune the setting file: adjust
boostvalues, switch a field fromtexttongram, or change the sort order. Then rebuild again.
Tip
Type bm ? in Alfred to jump straight to bookmarks-setting.json
in Finder. Edit, save, rebuild, and test — all without leaving your
current context.
Hosting Data Remotely¶
If you want to share your dataset with others, or keep it up to date without
manually replacing the local file, host the JSON somewhere and add
data_url to the setting file:
"data_url": "https://example.com/my-bookmarks-data.json"
Supported formats: .json and .json.zip. The file is downloaded
automatically when the index does not exist or after rebuild-index.
Others who install your workflow only need the -setting.json file; the
data is fetched for them.