1.. _Searching:
2
3Searching Your Library
4======================
5
6Pretty much every view in Quod Libet contains a search entry where you can
7enter search terms and save them. Quod Libet will search in artist, album,
8title, version, and any other visible columns for what you enter.
9
10If that's enough for you, you can stop reading now. But what if you want
11something more powerful?
12
13
14Combining Searches and Negation
15-------------------------------
16
17You can combine search terms using ``&`` ("and") and ``|`` ("or").
18
19If you want to listen to Electronic music but no Ambient::
20
21    &(electro, !ambient)
22
23Or you want to get all songs by `Neutral Milk Hotel
24<https://en.wikipedia.org/wiki/Neutral_Milk_Hotel>`_ including the solo
25performances of `Jeff Mangum <https://en.wikipedia.org/wiki/Jeff_Mangum>`_::
26
27    |(mangum, neutral milk)
28
29You can get all songs that don't match the search term using ``!``::
30
31    !electro
32
33Lets say you want to listen to you whole library but are not in the mood
34for classical music or songs by `The Smiths
35<https://en.wikipedia.org/wiki/The_Smiths>`_::
36
37    !|(classical, smiths)
38
39While these searches are easy to type in, they depend on the visible columns
40and the active browser, also the last one might exclude some songs which
41happen to contain "smiths" in their album title
42- see below for how to perform more targeted searching.
43
44
45Searching a Specific Tag
46------------------------
47
48To search a specific tag, use a search like::
49
50    artist = delerium
51    album = bargainville
52
53The search terms can't use quotes (``"``), slashes (``/``), hashes (``#``),
54pipes (``|``), ampersands (``&``), or bangs (``!``); these characters have
55special meanings for advanced searches. See :ref:`exact matching
56<exact_matching>` or :ref:`regular expressions <regular_expressions>` for how
57to do searches including these characters.
58
59In QL 3.9 onwards, you can also use `!=` to search for things not equal::
60
61    artist != delerium
62    genre != /.+ Jazz/
63
64
65You can also search :ref:`internal tags <InternalTags>`, e.g.
66
67 * ``~format = Ogg Vorbis``
68 * ``~dirname=Greatest Hits`` - search for all songs in Greatest Hits folders.
69
70It's also possible to search in multiple tags at once:
71
72 * ``artist, performer = "Boa"c``
73
74.. _exact_matching:
75
76Exact Matching
77--------------
78
79If you want an exact match, use quotes::
80
81    artist = "a girl called eddy"
82
83If you need to put a ``"`` inside the quotes, you can put a ``\`` before it::
84
85    version = "12\" mix"
86
87Other special characters can be used without escaping::
88
89    title = "Concertos #1"
90
91You can put a ``c`` after the last " to make the search case-sensitive::
92
93    artist = "BoA"c
94    artist = "Boa"c
95    artist != "Boa"c
96
97Combining Tag Searches
98----------------------
99
100As with free-text searches, you can combine searches using ``&`` ("and") and
101``|``  ("or"); either grouping entire searches, or just the tag values.
102Although the examples below use simple keywords, you can also use exact
103matches or regular expressions::
104
105    artist = |(Townshend, Who)
106    &(artist = Lindsay Smith, album = Vat)
107
108The first finds anything by `The Who <https://en.wikipedia.org/wiki/The_Who>`_
109or guitarist `Pete Townshend <https://en.wikipedia.org/wiki/Pete_Townshend>`_
110. The second gives the songs that match both, so you'll find songs Lindsay
111Smith's `Tales From The Fruitbat Vat
112<https://store.cdbaby.com/cd/lindsaysmith>`__, but not her other albums.
113
114You can also pick out all the songs that *don't* match the terms you give,
115using ``!``::
116
117    genre = !Audiobook
118
119is probably a good idea when playing your whole library on shuffle.
120Note again that in QL 3.9 onwards you can use the alternative syntax of::
121
122    genre != Audiobook
123
124
125More complex searches are of course possible. For example, to select all
126Disco and Jazz related (_containing_, technically) genres,
127but avoiding Acid Jazz, you could use::
128
129    genre = &(|(Disco, Jazz), !Acid Jazz)
130
131
132Numeric Searches
133----------------
134
135Using ``#``, you can search your library using numeric values. Quod Libet
136keeps some internal numeric values including ``track``, ``disc``,
137``rating``, ``length`` etc. See :ref:`numeric-tags` for full details. You
138can also search any other tag as long as the values have a number format
139like ``1234`` or ``-42.42``, for example ``year`` or ``bpm``.
140
141For comparisons you can then use typical binary operators like ``=``,
142``<``, ``>``, ``<=``, ``>=`` and ``!=``.
143
144 * ``#(skipcount > 100)`` could find really unpopular songs, or
145 * ``#(track > 50)`` to figure out who makes really insane albums, or
146 * ``#(bpm > 160)`` to find really fast songs
147
148You can also use chained comparisons:
149 * ``#(10 <= track < 100)`` to find all two-digit tracks.
150
151Times like ``added`` are stored in seconds, which is pretty cumbersome to
152search on. Instead, you can search with semi-English,
153like:
154
155 * ``#(added < 1 day)`` for very recently added tracks
156
157to find songs added in the last day (if you think that that's backwards,
158mentally add 'ago' when you read it). Quod Libet knows about seconds,
159minutes, hours, days, months (30 days), and years (365 days), kB
160(Kilobyte), MB (Megabyte), GB (Gigabyte). You can also use ''HH:MM''
161notation, like:
162
163 * ``#(2:00 < length < 3:00)`` for songs between two and three minutes long.
164
165Of course, you can combine numeric with other kinds of searches.
166
167 * ``&(genre = classical, #(lastplayed > 3 days))``
168 * ``&(artist = "Rush", #(year <= 1996))``
169
170
171Playlists
172---------
173
174You can use the ``~playlists`` internal tag to search by playlists. It is
175populated with a list of all the playlists that song appears in. This is
176surprisingly powerful if you're a playlist user.
177
178 * ``~playlists=chilled`` will return all songs included in any playlist
179   with "chilled" in its name.
180 * ``~playlists=|("Chilled", "Jazzy")`` for all songs in either (or both)
181   of those playlists.
182 * ``&(#(rating>=0.75), ~playlists="")`` will return all high-rated songs
183   *not* in any playlist
184
185
186.. _regular_expressions:
187
188Regular Expressions
189-------------------
190
191Quod Libet also supports searching your library using ''regular expressions'',
192a common way of finding text for Unix applications. Regular expressions look
193like regular searches, except they use / instead of ", and some punctuation
194has special meaning. There are many good tutorials on the web, and useful
195online regex testers (such as `Regex Pal <https://www.regexpal.com/>`__)
196
197Some examples::
198
199    artist = !/\sRice/ (or in 3.9+: artist != /\sRice/)
200
201or using the default tags::
202
203    /^portis/
204
205Like with exact matches, append a `c` to make the search case-sensitive::
206
207    /Boa/c
208
209Regex searches can also be used to escape special characters not permitted in
210normal searches::
211
212    filename = /\/Music\/Alternative/
213
214Ignore Accents and Umlauts
215--------------------------
216
217Appending a ``d`` after searches makes it's characters match variants with
218accents, umlauts etc.
219
220Both ``/Sigur Ros/d`` and ``"Sigur Ros"d`` will match songs with the artist
221name ``"Sigur Rós"``.
222
223
224Now you can search anything!
225
226Pluggable query expressions
227---------------------------
228
229More recent versions of Quod Libet allow queries to include pluggable expressions.
230This uses the format ``@(plugin: body)`` where plugin is the ID of the query
231plugin (e.g. ``saved``, ``python``) - see ``quodlibet/ext/query/*``.
232
233From QL 3.10 onwards, the Python query plugin allows some use of external modules,
234notably `time` and `random`, as well as a few useful variables.
235
236For example, here is a way of simulating an album Spotlight in an album browser:
237
238``@(python: Random((int(_ts / 60), a)).random() < 0.01)``
239
240Here ``_ts`` is a current timestamp, and ``a`` is the album data.
241So this generates a random number seeded on the current minute and the album key,
242so we randomly select 1% of our albums to look at.
243
244Reusing queries
245---------------
246
247Complex queries can be split into simpler ones.  Also, a query can be reused
248in other ones.  This way it is easier to change and administer your searches.
249
250In order to do so, the ``Include Saved Search`` query plugin (see above) must be activated.
251If you create a saved search named ``Unrated`` you can search for unrated songs from the Beatles
252like this:
253
254``&(@(saved: Unrated), Beatles)``
255
256For creating saved searches, use the "Edit saved searches..." item in the drop-down
257at the right of the query text box.
258