Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Is there a 'fuzzy search' API in foobar? (Read 3011 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Is there a 'fuzzy search' API in foobar?

I'd like to search the library for exact and inexact matches of some tags. Ideally this would be some library API to query for an artist and get returned a list of (track, relevance) pairs, where some tracks that don't quite match (e.g. different punctuation, capitalisation, perhaps slight variations in spelling) are returned with lower relevance.

So far the only way I've seen of querying the library is something like this, taken from foo_scrobblecharts:

Code: [Select]
// database needs to be locked for this to work
inline bool isTrackByArtist(const char * artist,metadb_handle_ptr &track){
    const file_info * fileInfo;
    if (track->get_info_async_locked(fileInfo)){
        for (int j=0; j < fileInfo->meta_get_count_by_name("artist"); j++){
            if(stricmp_utf8(fileInfo->meta_get("artist", j), artist) == 0){
                return true;
            }
        }
    }
    return false;
}

// database has to be locked before calling this function
void filterTracksByArtist(const char * artist, pfc::list_base_t<metadb_handle_ptr> &p_data){
    t_size n = p_data.get_count();
    bit_array_bittable deleteMask(n);
    for (int i = 0; i < n; i++){
        const file_info * fileInfo;
        deleteMask.set(i,!isTrackByArtist(artist,p_data[i]));
    }
    p_data.remove_mask(deleteMask);
}

...

pfc::list_t<metadb_handle_ptr> library;
static_api_ptr_t<library_manager> lm;
lm->get_all_items(library);
filterTracksByArtist("Some Artist",library);


Clearly this is literally grabbing everything from the library, then stripping that down to only items exactly matching the artist name passed in (albeit with a case-insensitive compare). This doesn't seem like a very efficient way of doing things to me; surely foobar stores metadata in a database, and that database has some efficient query mechanism developers can use? But that aside, would I have to implement fuzzy search myself by essentially iterating over everything in the library and doing some check more complicated than stricmp, and storing the relevance for each item? This sounds like it would make the inefficiency much, much worse. I'm hoping there's some API in place for this already since I've seen a few components use some kind of fuzzy search.

Is there a 'fuzzy search' API in foobar?

Reply #1
This doesn't seem like a very efficient way of doing things to me; surely foobar stores metadata in a database, and that database has some efficient query mechanism developers can use?
There is no (relational) database.

But that aside, would I have to implement fuzzy search myself by essentially iterating over everything in the library and doing some check more complicated than stricmp, and storing the relevance for each item?
I'm pretty sure that is what everyone else does.

IIRC there is an API for auto-completion which could provide you with the list of all values of particular tags. However that still doesn't give you the corresponding tracks.

Is there a 'fuzzy search' API in foobar?

Reply #2
Ah right, so the only library query mechanism is to get all tracks? It sounds crazy to me, but if that's what all other components do then I guess it's not a problem, since I've yet to encounter a component that is noticeably slow at searching.

Same goes for fuzzy searching; if that's what other components do then I'll do the same. I don't suppose you know of any components that implement fuzzy search that have source available do you? I'd like to re-invent as few wheels as possible

Is there a 'fuzzy search' API in foobar?

Reply #3
Look here and use foobar query syntax.
Although not exactly fuzzy, you can use wildcards (* and ?) to cope with a number of situations.