{"id":1812,"date":"2020-07-04T11:39:51","date_gmt":"2020-07-04T09:39:51","guid":{"rendered":"https:\/\/www.speich.net\/articles\/?p=1812"},"modified":"2020-10-17T10:47:37","modified_gmt":"2020-10-17T08:47:37","slug":"php-and-sqlite-fts4-how-to-process-the-matchinfo-function","status":"publish","type":"post","link":"https:\/\/www.speich.net\/articles\/en\/2020\/07\/04\/php-and-sqlite-fts4-how-to-process-the-matchinfo-function\/","title":{"rendered":"PHP and SQLite FTS4: How to process the matchinfo function part I"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Reading the binary output from the matchinfo() function<\/h2>\n\n\n\n<p>SQLite&#8217;s <a rel=\"noreferrer noopener\" href=\"https:\/\/www.sqlite.org\/fts3.html#matchinfo\" target=\"_blank\">MATCHINFO() function<\/a> provides metrics that are useful for filtering or sorting results of a query according to relevance. The function returns a binary string representing a variable number of 32-bit unsigned integers in machine byte-order. It can be read into an array of integers using the PHP <a rel=\"noreferrer noopener\" href=\"https:\/\/www.php.net\/manual\/en\/function.unpack.php\" target=\"_blank\">unpack() function<\/a> passing <code class=\"language-php\">'L*'<\/code> as the format parameter.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>The code below re-creates the example and output from the FTS3\/FTS4 documentation. First of all, we construct the <code class=\"language-php\">sample.sqlite<\/code> database file and create the virtual FTS4 table <code class=\"language-php\">t1<\/code> with the two columns <code class=\"language-php\">a<\/code> and <code class=\"language-php\">b<\/code>. Secondly, we populate the table with data from the example:<\/p>\n\n\n\n<pre class=\"language-php\"><code>\n\/\/ create the SQLite database example.sqlite\ntry {\n    $db = new PDO('sqlite:example.sqlite');\n} catch (PDOException $error) {\n    echo $error-&gt;getMessage();\n}\n\n\/\/ populate the database with data\ntry {\n    $db-&gt;exec(\"CREATE VIRTUAL TABLE t1 USING fts4(a, b);\n        INSERT INTO t1 VALUES('transaction default models default', 'Non transaction reads');\n        INSERT INTO t1 VALUES('the default transaction', 'these semantics present');\n        INSERT INTO t1 VALUES('single request', 'default data');\");\n\n} catch (PDOException $error) {\n    echo $error-&gt;getMessage().'<br>';\n}\n<\/code><\/pre>\n\n\n\n<p>Next, we query the data in the table <code class=\"language-php\">t1<\/code> using the <code class=\"language-php\">matchinfo(t1, 'pcx')<\/code> function with the default parameters <code class=\"language-php\">'pcx'<\/code> for the second function argument (shown for clarity, can be omitted). Then we print the result of the query in a while loop using <code class=\"language-php\">unpack('L*', $row['info1'])<\/code> to convert the binary blob into an array of integers <code class=\"language-php\">$arrInt32<\/code>. Finally, we format the array of integers with our function <code class=\"language-php\">formatOutput($arrInt32)<\/code> in groups of three using the modulo <code class=\"language-php\">%<\/code>:<\/p>\n\n\n\n<pre class=\"language-php\"><code>\n\/\/ query the database using the matchinfo() function\n$data = $db-&gt;query(\"SELECT MATCHINFO(t1, 'pcx') info1 FROM t1 WHERE t1 MATCH 'default transaction \\\"these semantics\\\"'\");\n\n\/\/ convert, format and print the output of the query\nwhile ($row = $data-&gt;fetch(PDO::FETCH_ASSOC)) {\n    \/\/ matchinfo returns a blob of 32-bit unsigned integers in machine byte-order\n    \/\/ note: returned array starts with index 1 and not 0\n    $arrInt32 = unpack('L*', $row['info1']);\n    echo formatOutput($arrInt32).\"<br>\";\n}\n\n\/**\n * Formats the array of integers with spaces.\n * Formats the output with spaces according to the example in the SQLite FTS documentation.\n * @param array $arrInt32\n *\/\nfunction formatOutput($arrInt32)\n{\n    foreach ($arrInt32 as $i =&gt; $int) {\n        if ($i % 3 === 0) {\n            echo ' ';\n        }\n        echo $int;\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>Printed output: <code class=\"language-php\">32 132 011 122 011 000 111<\/code><\/p>\n\n\n\n<p>Find out what these integers represent in Part II: <a href=\"https:\/\/www.speich.net\/articles\/en\/2020\/08\/30\/php-and-sqlite-fts4-how-to-process-the-matchinfo-function-2\/\">Understanding the output from the matchinfo() function<\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reading the binary output from the matchinfo() function SQLite&#8217;s MATCHINFO() function provides metrics that are useful for filtering or sorting results of a query according to relevance. The function returns a binary string representing a variable number of 32-bit unsigned integers in machine byte-order. It can be read into an array of integers using the &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.speich.net\/articles\/en\/2020\/07\/04\/php-and-sqlite-fts4-how-to-process-the-matchinfo-function\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;PHP and SQLite FTS4: How to process the matchinfo function part I&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[285,284,82],"class_list":["post-1812","post","type-post","status-publish","format-standard","hentry","category-php","tag-fts3","tag-fts4","tag-sqlite","entry"],"_links":{"self":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1812","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/comments?post=1812"}],"version-history":[{"count":26,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1812\/revisions"}],"predecessor-version":[{"id":1936,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/posts\/1812\/revisions\/1936"}],"wp:attachment":[{"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/media?parent=1812"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/categories?post=1812"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.speich.net\/articles\/wp-json\/wp\/v2\/tags?post=1812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}