Skip to content

Commit

Permalink
* Fixed TWK-474: proper fulltext search.
Browse files Browse the repository at this point in the history
  • Loading branch information
muesli committed Mar 7, 2012
1 parent 6552dec commit 178aed9
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 121 deletions.
60 changes: 18 additions & 42 deletions src/libtomahawk/database/databasecommand_resolve.cpp
Expand Up @@ -81,11 +81,9 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
typedef QPair<int, float> scorepair_t;

// STEP 1
QList< QPair<int, float> > artists = lib->searchTable( "artist", m_query->artist(), false );
QList< QPair<int, float> > tracks = lib->searchTable( "track", m_query->track(), false );
QList< QPair<int, float> > albums = lib->searchTable( "album", m_query->album(), false );
QList< QPair<int, float> > tracks = lib->search( m_query );

if ( artists.length() == 0 || tracks.length() == 0 )
if ( tracks.length() == 0 )
{
qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track();
emit results( m_query->id(), res );
Expand All @@ -95,13 +93,10 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
// STEP 2
TomahawkSqlQuery files_query = lib->newquery();

QStringList artsl, trksl;
for ( int k = 0; k < artists.count(); k++ )
artsl.append( QString::number( artists.at( k ).first ) );
QStringList trksl;
for ( int k = 0; k < tracks.count(); k++ )
trksl.append( QString::number( tracks.at( k ).first ) );

QString artsToken = QString( "file_join.artist IN (%1)" ).arg( artsl.join( "," ) );
QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) );

QString sql = QString( "SELECT "
Expand All @@ -124,8 +119,7 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
"artist.id = file_join.artist AND "
"track.id = file_join.track AND "
"file.id = file_join.file AND "
"(%1 AND %2)" )
.arg( artsToken )
"(%1)" )
.arg( trksToken );

files_query.prepare( sql );
Expand Down Expand Up @@ -201,34 +195,9 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
typedef QPair<int, float> scorepair_t;

// STEP 1
QList< QPair<int, float> > artistPairs = lib->searchTable( "artist", m_query->fullTextQuery(), false, 20 );
QList< QPair<int, float> > albumPairs = lib->searchTable( "album", m_query->fullTextQuery(), false, 20 );
QList< QPair<int, float> > trackArtistPairs = lib->searchTable( "trackartist", m_query->fullTextQuery(), true, 20 );

if ( artistPairs.length() == 0 && albumPairs.length() == 0 && trackArtistPairs.length() == 0 )
{
qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track();
emit results( m_query->id(), res );
return;
}

foreach ( const scorepair_t& artistPair, artistPairs )
{
TomahawkSqlQuery query = lib->newquery();

QString sql = QString( "SELECT name FROM artist WHERE id = %1" ).arg( artistPair.first );
query.prepare( sql );
query.exec();

QList<Tomahawk::artist_ptr> artistList;
while ( query.next() )
{
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( artistPair.first, query.value( 0 ).toString() );
artistList << artist;
}
QList< QPair<int, float> > trackPairs = lib->search( m_query );
QList< QPair<int, float> > albumPairs = lib->searchAlbum( m_query, 20 );

emit artists( m_query->id(), artistList );
}
foreach ( const scorepair_t& albumPair, albumPairs )
{
TomahawkSqlQuery query = lib->newquery();
Expand All @@ -247,13 +216,20 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )

emit albums( m_query->id(), albumList );
}

if ( trackPairs.length() == 0 )
{
qDebug() << "No candidates found in first pass, aborting resolve" << m_query->fullTextQuery();
emit results( m_query->id(), res );
return;
}

// STEP 2
TomahawkSqlQuery files_query = lib->newquery();

QStringList trksl;
for ( int k = 0; k < trackArtistPairs.count(); k++ )
trksl.append( QString::number( trackArtistPairs.at( k ).first ) );
for ( int k = 0; k < trackPairs.count(); k++ )
trksl.append( QString::number( trackPairs.at( k ).first ) );

QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) );
QString sql = QString( "SELECT "
Expand Down Expand Up @@ -325,11 +301,11 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
result->setAlbumPos( files_query.value( 17 ).toUInt() );
result->setTrackId( files_query.value( 9 ).toUInt() );

for ( int k = 0; k < trackArtistPairs.count(); k++ )
for ( int k = 0; k < trackPairs.count(); k++ )
{
if ( trackArtistPairs.at( k ).first == (int)result->trackId() )
if ( trackPairs.at( k ).first == (int)result->trackId() )
{
result->setScore( trackArtistPairs.at( k ).second );
result->setScore( trackPairs.at( k ).second );
break;
}
}
Expand Down
42 changes: 21 additions & 21 deletions src/libtomahawk/database/databasecommand_updatesearchindex.cpp
Expand Up @@ -45,39 +45,39 @@ DatabaseCommand_UpdateSearchIndex::~DatabaseCommand_UpdateSearchIndex()


void
DatabaseCommand_UpdateSearchIndex::indexTable( DatabaseImpl* db, const QString& table, const QString& query )
DatabaseCommand_UpdateSearchIndex::exec( DatabaseImpl* db )
{
qDebug() << Q_FUNC_INFO;
db->m_fuzzyIndex->beginIndexing();

QMap< unsigned int, QMap< QString, QString > > data;
TomahawkSqlQuery q = db->newquery();
qDebug() << "Building index for" << table;
q.exec( QString( "SELECT %1" ).arg( query ) );

QMap< unsigned int, QString > fields;
QString value;
q.exec( "SELECT track.id, track.name, artist.name, artist.id FROM track, artist WHERE artist.id = track.artist" );
while ( q.next() )
{
value = "";
for ( int v = 1; v < q.record().count(); v++ )
value += q.value( v ).toString() + " ";
QMap< QString, QString > track;
track.insert( "track", q.value( 1 ).toString() );
track.insert( "artist", q.value( 2 ).toString() );
track.insert( "artistid", q.value( 3 ).toString() );

fields.insert( q.value( 0 ).toUInt(), value.trimmed() );
data.insert( q.value( 0 ).toUInt(), track );
}

db->m_fuzzyIndex->appendFields( table, fields );
qDebug() << "Building index for" << table << "finished.";
}
db->m_fuzzyIndex->appendFields( data );
data.clear();

q.exec( "SELECT album.id, album.name FROM album" );
while ( q.next() )
{
QMap< QString, QString > album;
album.insert( "album", q.value( 1 ).toString() );

void
DatabaseCommand_UpdateSearchIndex::exec( DatabaseImpl* db )
{
db->m_fuzzyIndex->beginIndexing();
data.insert( q.value( 0 ).toUInt(), album );
}

db->m_fuzzyIndex->appendFields( data );

indexTable( db, "artist", "id, name FROM artist" );
indexTable( db, "album", "id, name FROM album" );
indexTable( db, "track", "id, name FROM track" );
indexTable( db, "trackartist", "track.id, artist.name, track.name FROM track, artist WHERE artist.id = track.artist" );
qDebug() << "Building index finished.";

db->m_fuzzyIndex->endIndexing();
}
6 changes: 0 additions & 6 deletions src/libtomahawk/database/databasecommand_updatesearchindex.h
Expand Up @@ -35,13 +35,7 @@ Q_OBJECT
virtual bool doesMutates() const { return true; }
virtual void exec( DatabaseImpl* db );

signals:
void indexUpdated();

private:
void indexTable( DatabaseImpl* db, const QString& table, const QString& query );

QString table;
IndexingJobItem* m_statusJob;
};

Expand Down
31 changes: 27 additions & 4 deletions src/libtomahawk/database/databaseimpl.cpp
Expand Up @@ -78,7 +78,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
// in case of unclean shutdown last time:
query.exec( "UPDATE source SET isonline = 'false'" );

// schemaUpdated = true; // REMOVE ME
schemaUpdated = true; // REMOVE ME
m_fuzzyIndex = new FuzzyIndex( *this, schemaUpdated );
if ( schemaUpdated )
QTimer::singleShot( 0, this, SLOT( updateIndex() ) );
Expand Down Expand Up @@ -409,13 +409,36 @@ DatabaseImpl::albumId( int artistid, const QString& name_orig, bool autoCreate )


QList< QPair<int, float> >
DatabaseImpl::searchTable( const QString& table, const QString& name, bool fulltext, uint limit )
DatabaseImpl::search( const Tomahawk::query_ptr& query, uint limit )
{
QList< QPair<int, float> > resultslist;
if ( table != "artist" && table != "track" && table != "album" && table != "trackartist" )

QMap< int, float > resultsmap = m_fuzzyIndex->search( query );
foreach ( int i, resultsmap.keys() )
{
resultslist << QPair<int, float>( i, (float)resultsmap.value( i ) );
}
qSort( resultslist.begin(), resultslist.end(), DatabaseImpl::scorepairSorter );

if ( !limit )
return resultslist;

QMap< int, float > resultsmap = m_fuzzyIndex->search( table, name, fulltext );
QList< QPair<int, float> > resultscapped;
for ( int i = 0; i < (int)limit && i < resultsmap.count(); i++ )
{
resultscapped << resultslist.at( i );
}

return resultscapped;
}


QList< QPair<int, float> >
DatabaseImpl::searchAlbum( const Tomahawk::query_ptr& query, uint limit )
{
QList< QPair<int, float> > resultslist;

QMap< int, float > resultsmap = m_fuzzyIndex->searchAlbum( query );
foreach ( int i, resultsmap.keys() )
{
resultslist << QPair<int, float>( i, (float)resultsmap.value( i ) );
Expand Down
5 changes: 2 additions & 3 deletions src/libtomahawk/database/databaseimpl.h
Expand Up @@ -56,7 +56,8 @@ friend class DatabaseCommand_UpdateSearchIndex;
int trackId( int artistid, const QString& name_orig, bool autoCreate );
int albumId( int artistid, const QString& name_orig, bool autoCreate );

QList< QPair<int, float> > searchTable( const QString& table, const QString& name, bool fulltext, uint limit = 0 );
QList< QPair<int, float> > search( const Tomahawk::query_ptr& query, uint limit = 0 );
QList< QPair<int, float> > searchAlbum( const Tomahawk::query_ptr& query, uint limit = 0 );
QList< int > getTrackFids( int tid );

static QString sortname( const QString& str, bool replaceArticle = false );
Expand All @@ -79,8 +80,6 @@ friend class DatabaseCommand_UpdateSearchIndex;
signals:
void indexReady();

public slots:

private slots:
void updateIndex();

Expand Down

0 comments on commit 178aed9

Please sign in to comment.