Open oknozor opened 5 years ago
I've been fiddling with search queries, and trying to figure out how search queries on other entities maybe implemented. I tried to implement searches based on the Release
type, but it seems like the API response further contains a release-group
key for every release item:
https://musicbrainz.org/ws/2/release/?query=release:Tonight,%20Tomorrow
This release-group
contains only two further subkeys, which are title
and primary-type
. So, the library is unable to parse this as a valid ReleaseGroup
struct, since our struct expects more than these 2 keys (which additionally includes the value for first-release-date
). How would we implement this? Should we change all of the missing attributes to Option<T>
? Or do we have a another approach in mind?
I think adding more optional will be confusing for the end user. It would be simpler to use an associated type to the Search
trait like so :
pub trait Search<'a> {
type SearchResult;
fn search(query: String) -> SearchQuery<Self::SearchResult>
// ....
This way we could define a custom struct to hold the search result or reuse an existing one when possible.
Which entity should I query if I want to auto-tag midi files based on artist and song title extracted from a midi filename? Should I query recordings, releases or works?
(Actually, the extraction is not trivial because the artist and song name can be in any order, with spelling mistakes, sometimes separated by -
, sometimes by _
, sometimes not separated, or with other punctuation in between, and sometimes the file name is only the artist or song name, sometimes even as one long word without spaces. So I need to do multiple queries to first determine which part is the artist and which is the song name. But maybe the API can meet me halfway with a certain endpoint that determines the artist and song name from a given filename string?)
This could be complex depending on how much you know about what is in your midi filename. Currently search is only implemented for artist, but as soon as other entity are implemented (very soon) you will be able to try this out.
Let say you are trying to auto-tag "IAM - Demain c'est loin.midi"
I would probably start with something like this :
curl --request GET \
--url 'https://musicbrainz.org/ws/2/recording/?query=title%3Ademain%20c'\''est%20loin%20AND%20artist%3Aiam%20OR%20artist%3ADemain%20c'\''est%20loin%20AND%20title%3Aiam%22&fmt=json'
This would translate into musicbrainz_rs (not implemented yet for recording) :
let query = Recording::query_builder()
.artist("Iam")
.and()
.title("Demain c'est loin")
.or()
.title(Iam")
.and()
.artist("Demain c'est loin")
.build();
let result = Artist::search(query).execute();
Also we currently don't expose the search score but this could be be useful for use cases like yours.
@ritiek do you think we could expose search score ?
@Boscop I think fuzzy search capabilities could be somewhat useful too if you suspect spelling mistakes in filenames.
@ritiek do you think we could expose search score ?
The API search response does expose a ns2:score
parameter. I think it would definitely be a good idea to support this in musicbrainz_rs.
@ritiek Does musicbrainz support fuzzy search, too? (Many file names have spelling mistakes.)
Yep, musicbrainz API does support it. Although I'm not sure how effective it would be for your use-case but it might be worth a try.
Does this crate pass it through? So could I use it for any entity lookup with this crate?
Yes, this crate will pass the fuzzy operator ~
to the musicbrainz API. But as @oknozor mentioned only artist search is implemented at the moment. So, something like this would work for fuzzy artist searches:
use musicbrainz_rs::entity::artist::Artist;
use musicbrainz_rs::prelude::*;
fn main() {
let query = String::from("query=artist:kayden~");
let query_result = Artist::search(query).execute().unwrap();
println!("{:?}", query_result);
}
@oknozor I'm also curious on whether name
is an actual searchable artist field? because I don't see it mentioned under artist search fields and it seems fuzzy searching an artist through name
field doesn't return any results: query=name:kayden~
While it works as expected when using the artist
field: query=artist:kayden~, but I'm not sure how to use Artist::query_builder()
to build the query in this case if it's currently possible (I wrote the query directly in the above code).
I'm also curious on whether name is an actual searchable artist field? because I don't see it mentioned under artist search fields and it seems fuzzy searching an artist through name field doesn't return any results: query=name:kayden~
I just checked you are correct. It was working previously with "name" because lucene seems to search on any field when the input field is unknown, unless you use fuzzy search.
We can fix this by adding #[query_builder_rename = "artist"]
on Artist.name
(see: https://github.com/oknozor/lucene_query_builder_rs#rename-fields).
see : https://musicbrainz.org/doc/MusicBrainz_API/Search