k4200’s notes and thoughts

Programmer side of k4200

PECLのSolrエクステンションをSolr 4に対応させる

PECLのSolrエクステンションはSolr 4では動かない

PECLのSolrエクステンションがあるんだけど、Solr 4ではcommitが上手く動かない(モジュールの最新バージョン1.0.2でもNG)。原因は`waitFlush`というパラメータが廃止になった?ため。詳しくはこの辺を参照。

動作させるには?

こちらに先の問題を修正したバージョンがあるので、これを使う(solr4-compatible という名前のブランチ)。

これのRPMを作っておいたほうが色々便利。以下、RPM作成の基本的な手順は知っている前提で。

SRPM取得、展開

まず、各ディストリビューションに対応したSRPMを持ってくる。Red Hat Enterprise LinuxCentOSの6の場合、EPELにphp-pecl-solrというパッケージがあるがバージョンが古いので、FedoraSRPMを使ったほうが良いと思う(この辺)。

で、それを展開。

$ rpm -ivh php-pecl-solr-1.0.2-4.fc18.src.rpm
パッチ作成

オフィシャルのエクステンションと上で紹介したSolr 4対応のものは、差分はわずか


以下の内容のパッチファイルを、 $rpmbuild/SOURCES/solr4.patch という名前で保存。

--- php_solr_client.c.org
+++ php_solr_client.c
@@ -1483,14 +1483,14 @@ static void solr_generate_document_xml_from_fields(xmlNode *solr_doc_node, HashT
 }
 /* }}} */
 
-/* {{{ proto SolrUpdateResponse SolrClient::optimize([string maxSegments [, bool waitFlush [, bool waitSearcher]])
+/* {{{ proto SolrUpdateResponse SolrClient::optimize([string maxSegments [, bool waitSearcher]])
    Sends an optimize XML request to the server. */
 PHP_METHOD(SolrClient, optimize)
 {
-	zend_bool waitFlush = 1, waitSearcher = 1;
+	zend_bool waitSearcher = 1;
 	char *maxSegments = "1";
 	int maxSegmentsLen = sizeof("1")-1;
-	char *waitFlushValue, *waitSearcherValue;
+	char *waitSearcherValue;
 	xmlNode *root_node = NULL;
 	xmlDoc *doc_ptr = NULL;
 	solr_client_t *client = NULL;
@@ -1499,20 +1499,18 @@ static void solr_generate_document_xml_from_fields(xmlNode *solr_doc_node, HashT
 	xmlChar *request_string = NULL;
 	zend_bool success = 1;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbb", &maxSegments, &maxSegmentsLen, &waitFlush, &waitSearcher) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbb", &maxSegments, &maxSegmentsLen, &waitSearcher) == FAILURE) {
 
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter");
 
 		return;
 	}
 
-	waitFlushValue = (waitFlush)? "true" : "false";
 	waitSearcherValue = (waitSearcher)? "true" : "false";
 
 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "optimize", &root_node);
 
 	xmlNewProp(root_node, (xmlChar *) "maxSegments", (xmlChar *) maxSegments);
-	xmlNewProp(root_node, (xmlChar *) "waitFlush", (xmlChar *) waitFlushValue);
 	xmlNewProp(root_node, (xmlChar *) "waitSearcher", (xmlChar *) waitSearcherValue);
 
 	if (solr_fetch_client_entry(getThis(), &client TSRMLS_CC) == FAILURE)
@@ -1554,14 +1552,14 @@ static void solr_generate_document_xml_from_fields(xmlNode *solr_doc_node, HashT
 }
 /* }}} */
 
-/* {{{ proto SolrUpdateResponse SolrClient::commit([string maxSegments [, bool waitFlush [, bool waitSearcher]])
+/* {{{ proto SolrUpdateResponse SolrClient::commit([string maxSegments [, bool waitSearcher]])
    Sends a commit XML request to the server. */
 PHP_METHOD(SolrClient, commit)
 {
-	zend_bool waitFlush = 1, waitSearcher = 1;
+	zend_bool waitSearcher = 1;
 	char *maxSegments = "1";
 	int maxSegmentsLen = sizeof("1")-1;
-	char *waitFlushValue, *waitSearcherValue;
+	char *waitSearcherValue;
 	xmlNode *root_node = NULL;
 	xmlDoc *doc_ptr = NULL;
 	solr_client_t *client = NULL;
@@ -1570,20 +1568,18 @@ static void solr_generate_document_xml_from_fields(xmlNode *solr_doc_node, HashT
 	xmlChar *request_string = NULL;
 	zend_bool success = 1;
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbb", &maxSegments, &maxSegmentsLen, &waitFlush, &waitSearcher) == FAILURE) {
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbb", &maxSegments, &maxSegmentsLen, &waitSearcher) == FAILURE) {
 
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter");
 
 		return;
 	}
 
-	waitFlushValue = (waitFlush)? "true" : "false";
 	waitSearcherValue = (waitSearcher)? "true" : "false";
 
 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "commit", &root_node);
 
 	xmlNewProp(root_node, (xmlChar *) "maxSegments", (xmlChar *) maxSegments);
-	xmlNewProp(root_node, (xmlChar *) "waitFlush", (xmlChar *) waitFlushValue);
 	xmlNewProp(root_node, (xmlChar *) "waitSearcher", (xmlChar *) waitSearcherValue);
 
 	if (solr_fetch_client_entry(getThis(), &client TSRMLS_CC) == FAILURE)
SPEC編集

上のパッチファイルを適用するようにSPECを編集。SPECファイルの差分は以下のような感じで。

--- php-pecl-solr.spec.org	2013-05-29 10:58:47.093056967 +0900
+++ php-pecl-solr.spec	2013-05-29 11:15:49.169815272 +0900
@@ -7,13 +7,14 @@
 Summary(fr):    API orientée objet pour Apache Solr
 Name:           php-pecl-solr
 Version:        1.0.2
-Release:        4%{?dist}
+Release:        4solr4%{?dist}
 License:        PHP
 Group:          Development/Languages
 URL:            http://pecl.php.net/package/solr
 
 Source0:        http://pecl.php.net/get/%{pecl_name}-%{version}.tgz
 Source2:        xml2changelog
+Patch0:         solr4.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires:  php-devel, php-pear, curl-devel, libxml2-devel
@@ -81,6 +82,7 @@
 %{_bindir}/php -n %{SOURCE2} package.xml >CHANGELOG
 
 cd %{pecl_name}-%{version}
+%patch0 -p0
 # Fix version
 sed -i -e '/PHP_SOLR_DOTTED_VERSION/s/1.0.1/1.0.2/' php_solr_version.h
RPMビルド

後は rpmbuild コマンドで(rpmbuildコマンドが無い場合は、rpm-buildパッケージをインストールする)。

まとめ

PECL SolrエクステンションはそのままだとSolr 4で上手く動かない。修正バージョンがあるので、それのRPMを作っておくといいと思うよ〜。

そして、PECL の Solr エクステンションは、早く1.0.3をリリースして欲しい。