Document.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php
  2. /**
  3. * Copyright (c) 2007-2011, Servigistics, Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * - Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * - Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * - Neither the name of Servigistics, Inc. nor the names of
  15. * its contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. * @copyright Copyright 2007-2011 Servigistics, Inc. (http://servigistics.com)
  31. * @license http://solr-php-client.googlecode.com/svn/trunk/COPYING New BSD
  32. * @version $Id: Document.php 54 2011-02-04 16:29:18Z donovan.jimenez $
  33. *
  34. * @package Apache
  35. * @subpackage Solr
  36. * @author Donovan Jimenez <djimenez@conduit-it.com>
  37. */
  38. /**
  39. * Holds Key / Value pairs that represent a Solr Document along with any associated boost
  40. * values. Field values can be accessed by direct dereferencing such as:
  41. * <code>
  42. * ...
  43. * $document->title = 'Something';
  44. * echo $document->title;
  45. * ...
  46. * </code>
  47. *
  48. * Additionally, the field values can be iterated with foreach
  49. *
  50. * <code>
  51. * foreach ($document as $fieldName => $fieldValue)
  52. * {
  53. * ...
  54. * }
  55. * </code>
  56. */
  57. class Apache_Solr_Document implements IteratorAggregate
  58. {
  59. /**
  60. * SVN Revision meta data for this class
  61. */
  62. const SVN_REVISION = '$Revision: 54 $';
  63. /**
  64. * SVN ID meta data for this class
  65. */
  66. const SVN_ID = '$Id: Document.php 54 2011-02-04 16:29:18Z donovan.jimenez $';
  67. /**
  68. * Document boost value
  69. *
  70. * @var float
  71. */
  72. protected $_documentBoost = false;
  73. /**
  74. * Document field values, indexed by name
  75. *
  76. * @var array
  77. */
  78. protected $_fields = array();
  79. /**
  80. * Document field boost values, indexed by name
  81. *
  82. * @var array array of floats
  83. */
  84. protected $_fieldBoosts = array();
  85. /**
  86. * Clear all boosts and fields from this document
  87. */
  88. public function clear()
  89. {
  90. $this->_documentBoost = false;
  91. $this->_fields = array();
  92. $this->_fieldBoosts = array();
  93. }
  94. /**
  95. * Get current document boost
  96. *
  97. * @return mixed will be false for default, or else a float
  98. */
  99. public function getBoost()
  100. {
  101. return $this->_documentBoost;
  102. }
  103. /**
  104. * Set document boost factor
  105. *
  106. * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
  107. */
  108. public function setBoost($boost)
  109. {
  110. $boost = (float) $boost;
  111. if ($boost > 0.0)
  112. {
  113. $this->_documentBoost = $boost;
  114. }
  115. else
  116. {
  117. $this->_documentBoost = false;
  118. }
  119. }
  120. /**
  121. * Add a value to a multi-valued field
  122. *
  123. * NOTE: the solr XML format allows you to specify boosts
  124. * PER value even though the underlying Lucene implementation
  125. * only allows a boost per field. To remedy this, the final
  126. * field boost value will be the product of all specified boosts
  127. * on field values - this is similar to SolrJ's functionality.
  128. *
  129. * <code>
  130. * $doc = new Apache_Solr_Document();
  131. *
  132. * $doc->addField('foo', 'bar', 2.0);
  133. * $doc->addField('foo', 'baz', 3.0);
  134. *
  135. * // resultant field boost will be 6!
  136. * echo $doc->getFieldBoost('foo');
  137. * </code>
  138. *
  139. * @param string $key
  140. * @param mixed $value
  141. * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
  142. */
  143. public function addField($key, $value, $boost = false)
  144. {
  145. if (!isset($this->_fields[$key]))
  146. {
  147. // create holding array if this is the first value
  148. $this->_fields[$key] = array();
  149. }
  150. else if (!is_array($this->_fields[$key]))
  151. {
  152. // move existing value into array if it is not already an array
  153. $this->_fields[$key] = array($this->_fields[$key]);
  154. }
  155. if ($this->getFieldBoost($key) === false)
  156. {
  157. // boost not already set, set it now
  158. $this->setFieldBoost($key, $boost);
  159. }
  160. else if ((float) $boost > 0.0)
  161. {
  162. // multiply passed boost with current field boost - similar to SolrJ implementation
  163. $this->_fieldBoosts[$key] *= (float) $boost;
  164. }
  165. // add value to array
  166. $this->_fields[$key][] = $value;
  167. }
  168. /**
  169. * Handle the array manipulation for a multi-valued field
  170. *
  171. * @param string $key
  172. * @param string $value
  173. * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
  174. *
  175. * @deprecated Use addField(...) instead
  176. */
  177. public function setMultiValue($key, $value, $boost = false)
  178. {
  179. $this->addField($key, $value, $boost);
  180. }
  181. /**
  182. * Get field information
  183. *
  184. * @param string $key
  185. * @return mixed associative array of info if field exists, false otherwise
  186. */
  187. public function getField($key)
  188. {
  189. if (isset($this->_fields[$key]))
  190. {
  191. return array(
  192. 'name' => $key,
  193. 'value' => $this->_fields[$key],
  194. 'boost' => $this->getFieldBoost($key)
  195. );
  196. }
  197. return false;
  198. }
  199. /**
  200. * Set a field value. Multi-valued fields should be set as arrays
  201. * or instead use the addField(...) function which will automatically
  202. * make sure the field is an array.
  203. *
  204. * @param string $key
  205. * @param mixed $value
  206. * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
  207. */
  208. public function setField($key, $value, $boost = false)
  209. {
  210. $this->_fields[$key] = $value;
  211. $this->setFieldBoost($key, $boost);
  212. }
  213. /**
  214. * Get the currently set field boost for a document field
  215. *
  216. * @param string $key
  217. * @return float currently set field boost, false if one is not set
  218. */
  219. public function getFieldBoost($key)
  220. {
  221. return isset($this->_fieldBoosts[$key]) ? $this->_fieldBoosts[$key] : false;
  222. }
  223. /**
  224. * Set the field boost for a document field
  225. *
  226. * @param string $key field name for the boost
  227. * @param mixed $boost Use false for default boost, else cast to float that should be > 0 or will be treated as false
  228. */
  229. public function setFieldBoost($key, $boost)
  230. {
  231. $boost = (float) $boost;
  232. if ($boost > 0.0)
  233. {
  234. $this->_fieldBoosts[$key] = $boost;
  235. }
  236. else
  237. {
  238. $this->_fieldBoosts[$key] = false;
  239. }
  240. }
  241. /**
  242. * Return current field boosts, indexed by field name
  243. *
  244. * @return array
  245. */
  246. public function getFieldBoosts()
  247. {
  248. return $this->_fieldBoosts;
  249. }
  250. /**
  251. * Get the names of all fields in this document
  252. *
  253. * @return array
  254. */
  255. public function getFieldNames()
  256. {
  257. return array_keys($this->_fields);
  258. }
  259. /**
  260. * Get the values of all fields in this document
  261. *
  262. * @return array
  263. */
  264. public function getFieldValues()
  265. {
  266. return array_values($this->_fields);
  267. }
  268. /**
  269. * IteratorAggregate implementation function. Allows usage:
  270. *
  271. * <code>
  272. * foreach ($document as $key => $value)
  273. * {
  274. * ...
  275. * }
  276. * </code>
  277. */
  278. public function getIterator()
  279. {
  280. $arrayObject = new ArrayObject($this->_fields);
  281. return $arrayObject->getIterator();
  282. }
  283. /**
  284. * Magic get for field values
  285. *
  286. * @param string $key
  287. * @return mixed
  288. */
  289. public function __get($key)
  290. {
  291. if (isset($this->_fields[$key]))
  292. {
  293. return $this->_fields[$key];
  294. }
  295. return null;
  296. }
  297. /**
  298. * Magic set for field values. Multi-valued fields should be set as arrays
  299. * or instead use the addField(...) function which will automatically
  300. * make sure the field is an array.
  301. *
  302. * @param string $key
  303. * @param mixed $value
  304. */
  305. public function __set($key, $value)
  306. {
  307. $this->setField($key, $value);
  308. }
  309. /**
  310. * Magic isset for fields values. Do not call directly. Allows usage:
  311. *
  312. * <code>
  313. * isset($document->some_field);
  314. * </code>
  315. *
  316. * @param string $key
  317. * @return boolean
  318. */
  319. public function __isset($key)
  320. {
  321. return isset($this->_fields[$key]);
  322. }
  323. /**
  324. * Magic unset for field values. Do not call directly. Allows usage:
  325. *
  326. * <code>
  327. * unset($document->some_field);
  328. * </code>
  329. *
  330. * @param string $key
  331. */
  332. public function __unset($key)
  333. {
  334. unset($this->_fields[$key]);
  335. unset($this->_fieldBoosts[$key]);
  336. }
  337. }