PageRenderTime 24ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/Search/src/abstraction/implementations/zend_lucene.php

https://github.com/Yannix/zetacomponents
PHP | 461 lines | 168 code | 36 blank | 257 comment | 13 complexity | 4aec809410b581a52ff3d284c865da06 MD5 | raw file
  1. <?php
  2. /**
  3. * File containing the ezcSearchQueryZendLucene class.
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. * @package Search
  23. * @version //autogen//
  24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25. * @ignore
  26. */
  27. /**
  28. * ezcSearchQueryZendLucene implements the find query for searching documents.
  29. *
  30. * @package Search
  31. * @version //autogen//
  32. * @ignore
  33. */
  34. class ezcSearchQueryZendLucene implements ezcSearchFindQuery
  35. {
  36. /**
  37. * Holds the columns to return in the search result
  38. *
  39. * @var array
  40. */
  41. public $resultFields;
  42. /**
  43. * Holds the columns to highlight in the search result
  44. *
  45. * @var array(string)
  46. */
  47. public $highlightFields;
  48. /**
  49. * Holds all the search clauses that will be used to create the search query.
  50. *
  51. * @var array(string)
  52. */
  53. public $whereClauses;
  54. /**
  55. * Holds all the order by clauses that will be used to create the search query.
  56. *
  57. * @var array(string)
  58. */
  59. public $orderByClauses;
  60. /**
  61. * Holds the maximum number of results for the query.
  62. *
  63. * @var int
  64. */
  65. public $limit = null;
  66. /**
  67. * Holds the number of the first element to return in the results.
  68. *
  69. * This is used in combination with the $limit option.
  70. *
  71. * @var int
  72. */
  73. public $offset;
  74. /**
  75. * Holds all the facets
  76. *
  77. * @var array(string)
  78. */
  79. public $facets;
  80. /**
  81. * Holds the search handler for which this query is built.
  82. *
  83. * @var ezcSearchHandler
  84. */
  85. private $handler;
  86. /**
  87. * Contains the document definition for which this query is built.
  88. *
  89. * @param ezcSearchDocumentDefinition $definition
  90. */
  91. private $definition;
  92. /**
  93. * Constructs a new ezcSearchQueryZendLucene object for the handler $handler
  94. *
  95. * The handler implements mapping field names and values based on the
  96. * document $definition.
  97. *
  98. * @param ezcSearchHandler $handler
  99. * @param ezcSearchDocumentDefinition $definition
  100. */
  101. public function __construct( ezcSearchHandler $handler, ezcSearchDocumentDefinition $definition )
  102. {
  103. $this->handler = $handler;
  104. $this->definition = $definition;
  105. $this->reset();
  106. }
  107. /**
  108. * Resets all the internal query values to their defaults.
  109. */
  110. public function reset()
  111. {
  112. $this->resultFields = array();
  113. $this->highlightFields = array();
  114. $this->whereClauses = array();
  115. $this->limit = null;
  116. $this->offset = 0;
  117. $this->facets = array();
  118. }
  119. /**
  120. * Returns the definition that belongs to this query
  121. *
  122. * @return ezcSearchDocumentDefinition
  123. */
  124. function getDefinition()
  125. {
  126. return $this->definition;
  127. }
  128. /**
  129. * Returns the query as a string for debugging purposes
  130. *
  131. * @return string
  132. * @ignore
  133. */
  134. public function getQuery()
  135. {
  136. return $this->handler->getQuery( $this );
  137. }
  138. /**
  139. * Checks whether the field $field exists in the definition.
  140. *
  141. * @param string $field
  142. * @throws ezcSearchFieldNotDefinedException if the field is not defined.
  143. */
  144. private function checkIfFieldExists( $field )
  145. {
  146. if ( !isset( $this->definition->fields[$field] ) )
  147. {
  148. throw new ezcSearchFieldNotDefinedException( $this->definition->documentType, $field );
  149. }
  150. }
  151. /**
  152. * Adds the fields to return in the results.
  153. *
  154. * This method accepts either an array of fieldnames, but can also accept
  155. * multiple parameters as field names. The following is therefore
  156. * equivalent:
  157. * <code>
  158. * $q->select( array( 'one', 'two', 'three' ) );
  159. * $q->select( 'one', 'two', 'three' ) );
  160. * </code>
  161. *
  162. * If fields already have been added with this function, they will not be
  163. * overwritten when this function is called subsequently.
  164. *
  165. * @param mixed $...
  166. * @return ezcSearchQueryZendLucene
  167. */
  168. public function select()
  169. {
  170. $args = func_get_args();
  171. $cols = ezcSearchQueryTools::arrayFlatten( $args );
  172. $this->resultFields = array_merge( $this->resultFields, $cols );
  173. return $this;
  174. }
  175. /**
  176. * Adds the fields to highlight in the results.
  177. *
  178. * This method accepts either an array of fieldnames, but can also accept
  179. * multiple parameters as field names. The following is therefore
  180. * equivalent:
  181. * <code>
  182. * $q->highlight( array( 'one', 'two', 'three' ) );
  183. * $q->highlight( 'one', 'two', 'three' ) );
  184. * </code>
  185. *
  186. * If fields already have been added with this function, they will not be
  187. * overwritten when this function is called subsequently.
  188. *
  189. * @param mixed $...
  190. * @return ezcSearchQueryZendLucene
  191. */
  192. public function highlight()
  193. {
  194. $args = func_get_args();
  195. $cols = ezcSearchQueryTools::arrayFlatten( $args );
  196. $this->highlightFields = array_merge( $this->highlightFields, $cols );
  197. return $this;
  198. }
  199. /**
  200. * Adds a select/filter statement to the query
  201. *
  202. * @param string $clause
  203. * @return ezcSearchQueryZendLucene
  204. */
  205. public function where( $clause )
  206. {
  207. $this->whereClauses[] = $clause;
  208. return $this;
  209. }
  210. /**
  211. * Registers from which offset to start returning results, and how many results to return.
  212. *
  213. * $limit controls the maximum number of rows that will be returned.
  214. * $offset controls which row that will be the first in the result
  215. * set from the total amount of matching rows.
  216. *
  217. * @param int $limit
  218. * @param int $offset
  219. * @return ezcSearchQueryZendLucene
  220. */
  221. public function limit( $limit, $offset = 0 )
  222. {
  223. $this->limit = $limit;
  224. $this->offset = $offset;
  225. return $this;
  226. }
  227. /**
  228. * Tells the query on which field to sort on, and in which order
  229. *
  230. * You can call orderBy multiple times. Each call will add a
  231. * column to order by.
  232. *
  233. * @param string $field
  234. * @param int $type
  235. * @return ezcSearchQueryZendLucene
  236. */
  237. public function orderBy( $field, $type = ezcSearchQueryTools::ASC )
  238. {
  239. $field = $this->handler->mapFieldType( $field, $this->definition->fields[$field]->type );
  240. $this->orderByClauses[$field] = $type;
  241. return $this;
  242. }
  243. /**
  244. * Adds one facet to the query.
  245. *
  246. * Facets should only be used for STRING fields, and not TEXT fields.
  247. *
  248. * @param string $facet
  249. * @return ezcSearchQueryZendLucene
  250. */
  251. public function facet( $facet )
  252. {
  253. $field = $this->handler->mapFieldType( $facet, $this->definition->fields[$facet]->type );
  254. $this->facets[] = $field;
  255. return $this;
  256. }
  257. /**
  258. * Returns a string containing a field/value specifier, and an optional boost value.
  259. *
  260. * The method uses the document definition field type to map the fieldname
  261. * to a solr fieldname, and the $fieldType argument to escape the $value
  262. * correctly. If a definition is set, the $fieldType will be overridden
  263. * with the type from the definition.
  264. *
  265. * @param string $field
  266. * @param mixed $value
  267. *
  268. * @return string
  269. */
  270. public function eq( $field, $value )
  271. {
  272. $field = trim( $field );
  273. $this->checkIfFieldExists( $field );
  274. $fieldType = $this->definition->fields[$field]->type;
  275. $value = $this->handler->mapFieldValueForSearch( $fieldType, $value );
  276. $fieldName = $this->handler->mapFieldType( $field, $this->definition->fields[$field]->type );
  277. $ret = "$fieldName:$value";
  278. if ( $this->definition->fields[$field]->boost != 1 )
  279. {
  280. $ret .= "^{$this->definition->fields[$field]->boost}";
  281. }
  282. return $ret;
  283. }
  284. /**
  285. * Returns a string containing a field/value specifier, and an optional boost value.
  286. *
  287. * The method uses the document definition field type to map the fieldname
  288. * to a solr fieldname, and the $fieldType argument to escape the values
  289. * correctly.
  290. *
  291. * @param string $field
  292. * @param mixed $value1
  293. * @param mixed $value2
  294. *
  295. * @return string
  296. */
  297. public function between( $field, $value1, $value2 )
  298. {
  299. $field = trim( $field );
  300. $this->checkIfFieldExists( $field );
  301. $fieldType = $this->definition->fields[$field]->type;
  302. $value1 = $this->handler->mapFieldValueForSearch( $fieldType, $value1 );
  303. $value2 = $this->handler->mapFieldValueForSearch( $fieldType, $value2 );
  304. $fieldName = $this->handler->mapFieldType( $field, $this->definition->fields[$field]->type );
  305. $ret = "$fieldName:[$value1 TO $value2]";
  306. if ( $this->definition->fields[$field]->boost != 1 )
  307. {
  308. $ret .= "^{$this->definition->fields[$field]->boost}";
  309. }
  310. return $ret;
  311. }
  312. /**
  313. * Creates an OR clause
  314. *
  315. * This method accepts either an array of fieldnames, but can also accept
  316. * multiple parameters as field names.
  317. *
  318. * @param mixed $...
  319. * @return string
  320. */
  321. public function lOr()
  322. {
  323. $args = func_get_args();
  324. if ( count( $args ) < 1 )
  325. {
  326. throw new ezcSearchQueryVariableParameterException( 'lOr', count( $args ), 1 );
  327. }
  328. $elements = ezcSearchQueryTools::arrayFlatten( $args );
  329. if ( count( $elements ) == 1 )
  330. {
  331. return $elements[0];
  332. }
  333. else
  334. {
  335. return '( ' . join( ' OR ', $elements ) . ' )';
  336. }
  337. }
  338. /**
  339. * Creates an AND clause
  340. *
  341. * This method accepts either an array of fieldnames, but can also accept
  342. * multiple parameters as field names.
  343. *
  344. * @param mixed $...
  345. * @return string
  346. */
  347. public function lAnd()
  348. {
  349. $args = func_get_args();
  350. if ( count( $args ) < 1 )
  351. {
  352. throw new ezcSearchQueryVariableParameterException( 'lAnd', count( $args ), 1 );
  353. }
  354. $elements = ezcSearchQueryTools::arrayFlatten( $args );
  355. if ( count( $elements ) == 1 )
  356. {
  357. return $elements[0];
  358. }
  359. else
  360. {
  361. return '( ' . join( ' AND ', $elements ) . ' )';
  362. }
  363. }
  364. /**
  365. * Creates a NOT clause
  366. *
  367. * This method accepts a clause and negates it.
  368. *
  369. * @param string $clause
  370. * @return string
  371. */
  372. public function not( $clause )
  373. {
  374. return "!$clause";
  375. }
  376. /**
  377. * Creates an 'important' clause
  378. *
  379. * This method accepts a clause and marks it as important.
  380. *
  381. * @param string $clause
  382. * @return string
  383. */
  384. public function important( $clause )
  385. {
  386. return "+$clause";
  387. }
  388. /**
  389. * Modifies a clause to give it higher weight while searching.
  390. *
  391. * This method accepts a clause and adds a boost factor.
  392. *
  393. * @param string $clause
  394. * @param float $boostFactor
  395. * @return string
  396. */
  397. public function boost( $clause, $boostFactor )
  398. {
  399. // make sure we only apply boost once
  400. if ( preg_match( '@(.*)\^[0-9]+(\.[0-9]+)?$@', $clause, $matches ) )
  401. {
  402. $clause = $matches[1];
  403. }
  404. return "$clause^$boostFactor";
  405. }
  406. /**
  407. * Modifies a clause make it fuzzy.
  408. *
  409. * This method accepts a clause and registers it as a fuzzy search, an
  410. * optional fuzz factor is also supported.
  411. *
  412. * @param string $clause
  413. * @param float $fuzzFactor
  414. * @return string
  415. */
  416. public function fuzz( $clause, $fuzzFactor = null )
  417. {
  418. if ( $fuzzFactor )
  419. {
  420. return "$clause~$fuzzFactor";
  421. }
  422. return "$clause~";
  423. }
  424. }
  425. ?>