Projects/Nepomuk/QueryingMethods: Difference between revisions

    From KDE TechBase
    (Marked this version for translation)
    (Removed page from translation)
     
    Line 1: Line 1:
    <languages />
    <translate>


    == Querying your Data == <!--T:1-->
    == Querying your Data ==


    <!--T:2-->
    There isn't much point of pushing all your data into Nepomuk, if you cannot query it. This article mentions the different ways you can query Nepomuk and the advantages and disadvantages of each.
    There isn't much point of pushing all your data into Nepomuk, if you cannot query it. This article mentions the different ways you can query Nepomuk and the advantages and disadvantages of each.


    == QueryServiceClient == <!--T:3-->
    == QueryServiceClient ==


    <!--T:4-->
    The Nepomuk [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html <tt>QueryServiceClient</tt>] is an asynchronous method of running queries in '''Nepomuk'''. It accepts both Nepomuk Queries and direct SPARQL queries. It provides convenient signal which your application can connect to in order to receive the results.
    The Nepomuk [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html <tt>QueryServiceClient</tt>] is an asynchronous method of running queries in '''Nepomuk'''. It accepts both Nepomuk Queries and direct SPARQL queries. It provides convenient signal which your application can connect to in order to receive the results.


    <!--T:5-->
    Please note that the asynchronous nature of the [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html QueryServiceClient] is achieved by transmitting the query over dbus to the storage service, where a new thread is spawned, the query is run on that thread, and the results are returned over dbus. This is fine for casual use, but when you care about high performance, it is recommended that you avoid the QueryServiceClient.
    Please note that the asynchronous nature of the [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html QueryServiceClient] is achieved by transmitting the query over dbus to the storage service, where a new thread is spawned, the query is run on that thread, and the results are returned over dbus. This is fine for casual use, but when you care about high performance, it is recommended that you avoid the QueryServiceClient.


    <!--T:6-->
    Example -
    Example -
    <syntaxhighlight lang="cpp-qt">
    <syntaxhighlight lang="cpp-qt">
    Line 40: Line 34:




    <!--T:7-->
    The [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html QueryServiceClient] also offers ways of updating the results via [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html#a1b843e5bf89ddb1a0d5c66eb0193375b entriesRemoved] and [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html#a6ed2be5579a00e9b8de1f5f23faf1fb6  newEntries]. While these methods may seem very attractive, their implementation is not. They work by running the entire query when some data in the Nepomuk database changes.
    The [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html QueryServiceClient] also offers ways of updating the results via [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html#a1b843e5bf89ddb1a0d5c66eb0193375b entriesRemoved] and [http://api.kde.org/4.x-api/kdelibs-apidocs/nepomuk-core/html/classNepomuk2_1_1Query_1_1QueryServiceClient.html#a6ed2be5579a00e9b8de1f5f23faf1fb6  newEntries]. While these methods may seem very attractive, their implementation is not. They work by running the entire query when some data in the Nepomuk database changes.


    <!--T:8-->
    In the future the queries will only be re-run when data related to the query changes (heuristics), but until then '''the entire query is re-run every time ANY data changes'''. Therefore it is recommended that you delete the QueryServiceClient when it has finished execution as follows -
    In the future the queries will only be re-run when data related to the query changes (heuristics), but until then '''the entire query is re-run every time ANY data changes'''. Therefore it is recommended that you delete the QueryServiceClient when it has finished execution as follows -


    <!--T:9-->
    <syntaxhighlight lang="cpp-qt">
    <syntaxhighlight lang="cpp-qt">
         Nepomuk2::Query::QueryServiceClient* client = new Nepomuk2::Query::QueryServiceClient( this );
         Nepomuk2::Query::QueryServiceClient* client = new Nepomuk2::Query::QueryServiceClient( this );
    Line 52: Line 43:
    </syntaxhighlight>
    </syntaxhighlight>


    == Result Iterator == <!--T:10-->
    == Result Iterator ==


    <!--T:11-->
    The <tt>ResultIterator</tt>, which has been introduced in 4.10, can take either a Nepomuk or SPARQL query and provides an iterator which you can use to get the results. The iterator is obviously blocking, so you may want to put it another thread, depending on the kind of query.
    The <tt>ResultIterator</tt>, which has been introduced in 4.10, can take either a Nepomuk or SPARQL query and provides an iterator which you can use to get the results. The iterator is obviously blocking, so you may want to put it another thread, depending on the kind of query.


    <!--T:12-->
    Example -
    Example -
    <syntaxhighlight lang="cpp-qt">
    <syntaxhighlight lang="cpp-qt">
    Line 67: Line 56:
                 QHashIterator<QUrl, Nepomuk2::Variant> it( prop );
                 QHashIterator<QUrl, Nepomuk2::Variant> it( prop );


                 <!--T:13-->
                 while( it.hasNext() ) {
    while( it.hasNext() ) {
                     it.next();
                     it.next();
                     kDebug() << it.key() << " " << it.value();
                     kDebug() << it.key() << " " << it.value();
    Line 78: Line 66:




    <!--T:14-->
    The ResultIterator is just a light wrapper over the <tt>Soprano::QueryResultIterator</tt>. It converts the bindings returned by the <tt>QueryResultIterator</tt> into a <tt>Query::Result</tt>.
    The ResultIterator is just a light wrapper over the <tt>Soprano::QueryResultIterator</tt>. It converts the bindings returned by the <tt>QueryResultIterator</tt> into a <tt>Query::Result</tt>.


    == Soprano::Model == <!--T:15-->
    == Soprano::Model ==


    <!--T:16-->
    The underlying '''Soprano''' model can also be used to directly run the queries. You can only run [[Projects/Nepomuk/SparqlQueries|SPARQL queries]] on the model. Use this method when you're writing a custom query. The underlying Model also provides an iterator similar to that of the <tt>ResultIterator</tt>.
    The underlying '''Soprano''' model can also be used to directly run the queries. You can only run [[Projects/Nepomuk/SparqlQueries|SPARQL queries]] on the model. Use this method when you're writing a custom query. The underlying Model also provides an iterator similar to that of the <tt>ResultIterator</tt>.


    <!--T:17-->
    Example -
    Example -
    <syntaxhighlight lang="cpp-qt">
    <syntaxhighlight lang="cpp-qt">
    Line 93: Line 78:
         Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
         Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );


         <!--T:18-->
         while( it.next() ) {
    while( it.next() ) {
             kDebug() << it["r"].uri();
             kDebug() << it["r"].uri();
         }
         }
    Line 100: Line 84:




    <!--T:19-->
    You might want to check out the [http://soprano.sourceforge.net/apidox/trunk/index.html Soprano API] for more information about the lower level details.
    You might want to check out the [http://soprano.sourceforge.net/apidox/trunk/index.html Soprano API] for more information about the lower level details.


    <!--T:20-->
    [[Category:Documentation]]
    [[Category:Documentation]]
    [[Category:Development]]
    [[Category:Development]]
    [[Category:Tutorials]]
    [[Category:Tutorials]]
    </translate>

    Latest revision as of 12:35, 9 February 2018

    Querying your Data

    There isn't much point of pushing all your data into Nepomuk, if you cannot query it. This article mentions the different ways you can query Nepomuk and the advantages and disadvantages of each.

    QueryServiceClient

    The Nepomuk QueryServiceClient is an asynchronous method of running queries in Nepomuk. It accepts both Nepomuk Queries and direct SPARQL queries. It provides convenient signal which your application can connect to in order to receive the results.

    Please note that the asynchronous nature of the QueryServiceClient is achieved by transmitting the query over dbus to the storage service, where a new thread is spawned, the query is run on that thread, and the results are returned over dbus. This is fine for casual use, but when you care about high performance, it is recommended that you avoid the QueryServiceClient.

    Example -

        Nepomuk2::Query::Query query( .. build Query .. );
        Nepomuk2::Query::QueryServiceClient* client = new Nepomuk2::Query::QueryServiceClient( this );
        client->query( query );
        connect( client, SIGNAL(newEntries(QList<Nepomuk2::Query::Result>)),
                 this, SLOT(newEntries(QList<Nepomuk2::Query::Result>)) );
        
        void TestObject::newEntries(const QList< Nepomuk2::Query::Result >& list)
        {
            foreach( const Nepomuk2::Query::Result &r, list ) {
                Nepomuk2::Resource res = r.resource();
                QHash<QUrl, Nepomuk2::Variant> prop = res.properties();
                QHashIterator<QUrl, Nepomuk2::Variant> it( prop );
                while( it.hasNext() ) {
                    it.next();
                    kDebug() << it.key() << " " << it.value();
                }
                kDebug() << "--------------------------";
            }
        }
    


    The QueryServiceClient also offers ways of updating the results via entriesRemoved and newEntries. While these methods may seem very attractive, their implementation is not. They work by running the entire query when some data in the Nepomuk database changes.

    In the future the queries will only be re-run when data related to the query changes (heuristics), but until then the entire query is re-run every time ANY data changes. Therefore it is recommended that you delete the QueryServiceClient when it has finished execution as follows -

        Nepomuk2::Query::QueryServiceClient* client = new Nepomuk2::Query::QueryServiceClient( this );
        connect( client, SIGNAL(finishedListing()), client, SLOT(deleteLater()) );
    

    Result Iterator

    The ResultIterator, which has been introduced in 4.10, can take either a Nepomuk or SPARQL query and provides an iterator which you can use to get the results. The iterator is obviously blocking, so you may want to put it another thread, depending on the kind of query.

    Example -

        Nepomuk2::Query::Query query( .. build Query .. );
        Nepomuk::Query::ResultIterator it( query );
        while( it.next() ) {
                Nepomuk2::Resource res = it.current().resource();
                QHash<QUrl, Nepomuk2::Variant> prop = res.properties();
                QHashIterator<QUrl, Nepomuk2::Variant> it( prop );
    
                while( it.hasNext() ) {
                    it.next();
                    kDebug() << it.key() << " " << it.value();
                }
                kDebug() << "--------------------------";
            }
        }
    


    The ResultIterator is just a light wrapper over the Soprano::QueryResultIterator. It converts the bindings returned by the QueryResultIterator into a Query::Result.

    Soprano::Model

    The underlying Soprano model can also be used to directly run the queries. You can only run SPARQL queries on the model. Use this method when you're writing a custom query. The underlying Model also provides an iterator similar to that of the ResultIterator.

    Example -

        QString query = QString::fromLatin1("select ?r where { ?r a nco:Contact . }");
        Soprano::Model* model = Nepomuk2::ResourceManager::instance()->mainModel();
        Soprano::QueryResultIterator it = model->executeQuery( query, Soprano::Query::QueryLanguageSparql );
    
        while( it.next() ) {
            kDebug() << it["r"].uri();
        }
    


    You might want to check out the Soprano API for more information about the lower level details.