Browse Source

- towards extensible searchd protocol

git-svn-id: svn://svn.sphinxsearch.com/sphinx/trunk@97 406a0c4d-033a-0410-8de8-e80135713968
shodan 21 years ago
parent
commit
0a47ba487c
5 changed files with 198 additions and 130 deletions
  1. 108 0
      api/sphinxapi.php
  2. 86 0
      api/test.php
  3. 0 130
      query.php
  4. 3 0
      src/searchd.cpp
  5. 1 0
      src/sphinx.h

+ 108 - 0
api/sphinxapi.php

@@ -0,0 +1,108 @@
+<?php
+
+//
+// $Id$
+//
+
+//
+// Copyright (c) 2001-2005, Andrew Aksyonoff. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License. You should have
+// received a copy of the GPL license along with this program; if you
+// did not, you can find it at http://www.gnu.org/
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// Sphinx PHP API
+/////////////////////////////////////////////////////////////////////////////
+
+/// this functions connects to sphinx searchd server,
+/// executes given query, and returns search results as a hash
+///
+/// $server is searchd server IP address or hostname
+/// $port is searchd server port
+/// $query is query string
+/// $start is offset into the result set to start retrieveing from
+/// $rpp is result count to retrieve (Rows Per Page)
+/// $weights is an array of weights for each index field
+/// $any is search mode, false to match all words and true to match any word
+/// $groups is an array of groups to limit matching to
+///
+/// returns false on failure
+/// returns hash which has the following keys on success:
+///		"matches"
+///			hash which maps found document_id to ( "weight", "group" ) hash
+///		"total"
+///			total matches count
+///		"time"
+///			search time
+///		"words"
+///			hash which maps query terms (stemmed!) to ( "docs", "hits" ) hash
+
+function sphinxQuery ( $server, $port, $query, $start=0, $rpp=20,
+	$weights=array(), $any=false, $groups=array() )
+{
+	$start = (int)$start;
+	$rpp = (int)$rpp;
+
+	if (!( $fp = @fsockopen ( $server, $port ) ) )
+		return false;
+
+	// check version
+	$s = trim ( fgets ( $fp, 1024 ) );
+	if ( $s!="VER 1" )
+	{
+		fclose ( $fp );
+		return false;
+	}
+
+	// build request
+	$req = pack ( "VVV", $start, $rpp, $any ? 1 : 0 ); // mode/limits part
+	$req .= pack ( "V", count($groups) ); // groups
+	foreach ( $groups as $group )
+		$req .= pack ( "V", $group );
+	$req .= pack ( "V", strlen($query) ) . $query; // query string
+	$req .= pack ( "V", count($weights) ); // weights
+	foreach ( $weights as $weight )
+		$req .= pack ( "V", (int)$weight );
+
+	// do query
+	fputs ( $fp, $req );
+
+	$result = array();
+	while ( !feof ( $fp ) )
+	{
+		$s = trim ( fgets ( $fp, 1024 ) );
+		if ( substr ( $s, 0, 6 )=="MATCH " )
+		{
+			list ( $dummy, $group, $doc, $weight ) = explode ( " ", $s );
+			$result["matches"][$doc] = array ( "weight" => $weight, "group" => $group );
+
+		} elseif ( substr ( $s, 0, 6 )=="TOTAL " )
+		{
+			$result["total"] = substr($s, 6);
+
+		} elseif ( substr ( $s, 0, 5 )=="TIME " )
+		{
+			$result["time"] = substr ( $s, 5 );
+
+		} elseif ( substr ( $s, 0, 5 ) == "WORD " )
+		{
+			list ( $dummy, $word, $docs, $hits ) = explode ( " ", $s );
+			$result["words"][$word]["docs"] = $docs;
+			$result["words"][$word]["hits"] = $hits;
+		}
+
+		// for now, simply ignore unknown response
+	}
+
+	fclose ( $fp );
+	return $result;
+}
+
+//
+// $Id$
+//
+
+?>

+ 86 - 0
api/test.php

@@ -0,0 +1,86 @@
+<?php
+
+//
+// $Id$
+//
+
+//
+// Copyright (c) 2001-2005, Andrew Aksyonoff. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License. You should have
+// received a copy of the GPL license along with this program; if you
+// did not, you can find it at http://www.gnu.org/
+//
+
+///////////////////////////////////////////////////////////////////////////////
+
+$searchd_host	= "127.0.0.1";
+$searchd_port	= 7812;
+
+///////////////////////////////////////////////////////////////////////////////
+
+require ( "sphinxapi.php" );
+
+// for very old PHP versions, like at my home test server
+if ( is_array($argv) && !isset($_SERVER["argv"]) )
+	$_SERVER["argv"] = $argv;
+unset ( $_SERVER["argv"][0] );
+
+// build query
+if ( !is_array($_SERVER["argv"]) || empty($_SERVER["argv"]) )
+	die ( "usage: php -f test.php [--any] <word [word [word [...]]]>\n" );
+
+$args = array();
+foreach ( $_SERVER["argv"] as $arg )
+	$args[] = $arg;
+
+$q = "";
+$any = false;
+$groups = array();
+for ( $i=0; $i<count($args); $i++ )
+{
+	if ( $args[$i]=="--any" )
+	{
+		$any = true;
+	} else if ( $args[$i]=="--group" )
+	{
+		$groups[] = (int)$args[++$i];
+	} else
+	{
+		$q .= $args[$i] . " ";
+	}
+}
+
+// do query
+$res = sphinxQuery ( $searchd_host, $searchd_port, $q, 0, 20, array(100,1), $any, $groups );
+if ( !$res )
+{
+	print "Query failed (searchd at $searchd_host:$searchd_port).\n";
+
+} else
+{
+	print "Query '$q' produced $res[total] matches in $res[time] sec.\n";
+	print "Query stats:\n";
+	if ( is_array($res["words"]) )
+		foreach ( $res["words"] as $word => $info )
+			print "    '$word' found $info[hits] times in $info[docs] documents\n";
+	print "\n";
+
+	if ( is_array($res["matches"]) )
+	{
+		$n = 1;
+		print "Matches:\n";
+		foreach ( $res["matches"] as $doc => $docinfo )
+		{
+			print "$n. doc_id=$doc, group=$docinfo[group], weight=$docinfo[weight]\n";
+			$n++;
+		}
+	}
+}
+
+//
+// $Id$
+//
+
+?>

+ 0 - 130
query.php

@@ -1,130 +0,0 @@
-<?php
-
-//
-// $Id$
-//
-
-//
-// Copyright (c) 2001-2005, Andrew Aksyonoff. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License. You should have
-// received a copy of the GPL license along with this program; if you
-// did not, you can find it at http://www.gnu.org/
-//
-
-/////////////////////////////////////////////////////////////////////////////
-// Sphinx PHP API
-/////////////////////////////////////////////////////////////////////////////
-
-$sphinx_server = "127.0.0.1";
-$sphinx_port   = 3312;
-
-function sphinxQuery ( $server, $port, $query, $start=0, $rpp=20, $weights=array(), $any=false, $groups=array() )
-{
-	$start = (int)$start;
-	$rpp = (int)$rpp;
-
-	if ( !($fp = fsockopen($server, $port)) )
-		return false;
-
-	// build request
-	$req = pack ( "VVV", $start, $rpp, $any ? 1 : 0 ); // mode/limits part
-	$req .= pack ( "V", count($groups) ); // groups
-	foreach ( $groups as $group )
-		$req .= pack ( "V", $group );
-	$req .= pack ( "V", strlen($query) ) . $query; // query string
-	$req .= pack ( "V", count($weights) ); // weights
-	foreach ( $weights as $weight )
-		$req .= pack ( "V", (int)$weight );
-
-	// do query
-	fputs ( $fp, $req );
-
-	$result = array();
-	while (!feof($fp)) {
-		$s = trim(fgets($fp, 1024));
-		if (substr($s, 0, 6) == "MATCH ") {
-			list($dummy, $group, $doc, $weight) = explode(" ", $s);
-			$result["matches"][$doc] = array ( "weight" => $weight, "group" => $group );
-			continue;
-		}
-		if (substr($s, 0, 6) == "TOTAL ") {
-			$result["total"] = substr($s, 6);
-			continue;
-		}
-		if (substr($s, 0, 5) == "TIME ") {
-			$result["time"] = substr($s, 5);
-			continue;
-		}
-		if (substr($s, 0, 5) == "WORD ") {
-			list($dummy, $word, $docs, $hits) = explode(" ", $s);
-			$result["words"][$word]["docs"] = $docs;
-			$result["words"][$word]["hits"] = $hits;
-			continue;
-		}
-	}
-
-	fclose($fp);
-	return $result;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-// for very old PHP versions, like at my home test server
-if ( is_array($argv) && !isset($_SERVER["argv"]) )
-	$_SERVER["argv"] = $argv;
-unset ( $_SERVER["argv"][0] );
-
-// build query
-if ( !is_array($_SERVER["argv"]) || empty($_SERVER["argv"]) )
-	die ( "usage: php -f query.php [--any] <word [word [word [...]]]>\n" );
-
-$args = array();
-foreach ( $_SERVER["argv"] as $arg )
-	$args[] = $arg;
-
-$q = "";
-$any = false;
-$groups = array();
-for ( $i=0; $i<count($args); $i++ )
-{
-	if ( $args[$i]=="--any" )
-	{
-		$any = true;
-	} else if ( $args[$i]=="--group" )
-	{
-		$groups[] = (int)$args[++$i];
-	} else
-	{
-		$q .= $args[$i] . " ";
-	}
-}
-
-// do query
-$res = sphinxQuery ( $sphinx_server, $sphinx_port, $q, 0, 20, array(100,1), $any, $groups );
-
-// print results
-print "Query '$q' produced $res[total] matches in $res[time] sec.\n";
-print "Query stats:\n";
-if ( is_array($res["words"]) )
-	foreach ( $res["words"] as $word => $info )
-		print "    '$word' found $info[hits] times in $info[docs] documents\n";
-print "\n";
-
-if ( is_array($res["matches"]) )
-{
-	$n = 1;
-	print "Matches:\n";
-	foreach ( $res["matches"] as $doc => $docinfo )
-	{
-		print "$n. doc_id=$doc, group=$docinfo[group], weight=$docinfo[weight]\n";
-		$n++;
-	}
-}
-
-//
-// $Id$
-//
-
-?>

+ 3 - 0
src/searchd.cpp

@@ -229,6 +229,9 @@ void HandleClient ( int rsock, CSphIndex * pIndex, CSphDict * pDict )
 	int i, iOffset, iLimit, iCount, iAny;
 	char sQuery [ 1024 ], sBuf [ 2048 ];
 
+	// hello there
+	iwrite ( rsock, "VER %d\n", SPHINX_SEARCHD_PROTO );
+
 	// read mode/limits
 	if ( iread ( rsock, &iOffset, 4 )!=4 ) return;
 	if ( iread ( rsock, &iLimit, 4 )!=4 ) return;

+ 1 - 0
src/sphinx.h

@@ -52,6 +52,7 @@
 
 #define SPHINX_VERSION			"0.9.2-dev"
 #define SPHINX_BANNER			"Sphinx " SPHINX_VERSION "\nCopyright (c) 2001-2005, Andrew Aksyonoff\n\n"
+#define SPHINX_SEARCHD_PROTO	1
 
 #define SPH_MAX_QUERY_WORDS		10
 #define SPH_MAX_WORD_LEN		64