songleaf.kaggle_index¶
A search index of the Kaggle corpus: the same songs and keys, without the corpus in memory.
KaggleChordsSource holds the whole corpus as a
DataFrame: about 1.1 GB per process, 1.6 GB once a lyrics search has run, and
every web worker holds its own copy. build_kaggle_index() writes it once
to one SQLite file beside the zip (datasets/chords-and-lyrics/): titles,
artists, popularity, each chart zlib-compressed, and an FTS5 table of the
charts’ words. KaggleChordsIndex reads that file. It keeps only the
titles, artists and popularity in memory (for fuzzy matching, a few tens of MB)
and answers lyrics searches and song lookups from disk.
Search results are the DataFrame source’s: the ranking code is shared, and only
where the data comes from differs. The one difference is how lyrics split into
words: FTS5’s tokenizer treats _ as a separator and does not compose
decomposed accents, where the DataFrame source’s regular expression does the
opposite. Rebuilding the index while a server runs is safe: a process that
notices the file changed reloads it.
The file format, its writing and its raw reads belong to sung.chords_index
(stdlib only, so reading the index never imports pandas); this module adds where
songleaf keeps the file and the ranking shared with the DataFrame source.
>>> import pandas as pd, tempfile, os
>>> corpus = pd.DataFrame({
... "Unnamed: 0": [1, 2], "artist_name": ["The Band", "Other"],
... "song_name": ["Paper Boats", "Quiet Road"], "lang": ["en", "en"],
... "popularity": [3, 1], "chords&lyrics": ["G\nPaper boats drift", "C\nquiet road"],
... })
>>> path = os.path.join(tempfile.mkdtemp(), "index.sqlite")
>>> build_kaggle_index(path=path, loader=lambda: corpus)["songs"]
2
>>> [hit.key for hit in KaggleChordsIndex(path).search(lyrics="boats")]
['kaggle_chords:1']
Module Attributes
The index's file name, beside the corpus zip under |
Functions
|
Write the index of the Kaggle corpus ( |
Where the index is read from: beside the corpus zip under the data root. |
Classes
|
The Kaggle corpus read from its index ( |
- songleaf.kaggle_index.KAGGLE_INDEX_NAME = 'chords-and-lyrics.sqlite'¶
The index’s file name, beside the corpus zip under
datasets/.
- class songleaf.kaggle_index.KaggleChordsIndex(path=None, *, min_score=70)[source]¶
Bases:
KaggleChordsSourceThe Kaggle corpus read from its index (
build_kaggle_index()).The same
nameand ids asKaggleChordsSource, so song keys and stored songs carry over. Only the columns fuzzy matching needs are held in memory; charts and lyrics matches come from the file.- search_tiers(query, *, limit=10)[source]¶
The songs whose title, artist or lyrics match
query, by where they match.{"title": [...], "artist": [...], "lyrics": [...]}, at mostlimitin each, best first. A song is in the first kind it matches, even when it ranks below the limit there, so a song is never shown as an artist match because more titles matched.Title and artist match word by word (
WordIndex): the query is inside the field ("wonder"finds Wonderwall) or the field is inside the query ("wonderwall oasis"finds the title Wonderwall and the artist Oasis), a word of four letters or more forgiving a typo; or every word of the query is in the title or in the artist ("paper boats invented band"). A song whose title holds a word of the query that its artist does not is a title match ("wonderwall oasis": Wonderwall (ver. 2) by Oasis), otherwise an artist match. Within each kind, the songs whose title and artist together hold the most words of the query come first (so Wonderwall by Oasis leads), then the closest by fuzzy score (of the title, or of title and artist, whichever is closer; of the artist), then the most popular. Lyrics hold every word of the query, rank by popularity, and carrymeta["snippet"]: the line that matched, with its spans.
- songleaf.kaggle_index.build_kaggle_index(*, path=None, loader=None, batch_size=5000)[source]¶
Write the index of the Kaggle corpus (
loader: as forKaggleChordsSource).Loading the corpus takes the memory the index exists to avoid, so run this once, apart from any server (
songleaf build-index). The index format and its writing aresung.chords_index’s; this picks the corpus and the path.- Return type: