菜谱项目

Solr.php 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. class Solr{
  3. /**
  4. * Solr资源串
  5. * @var string
  6. */
  7. public $dsn = 'http://59.110.214.36:8983/solr/';
  8. /**
  9. * Solr集合
  10. * @var string
  11. */
  12. public $core = 'food_list';
  13. /**
  14. * 设置集合
  15. * @param string $core 集合
  16. * @return Solr
  17. */
  18. function setCore($core)
  19. {
  20. $this->core = $core;
  21. return $this;
  22. }
  23. /**
  24. * 获取集合
  25. * @return string
  26. */
  27. function getCore()
  28. {
  29. return $this->core;
  30. }
  31. /**
  32. * Solr 搜索
  33. * @param string $action 方法
  34. * @param array $data 数据
  35. * @return array
  36. */
  37. function post($action, $data = array(), $redo = 5)
  38. {
  39. if (strpos($action, '?')) {
  40. $action .= '&wt=json';
  41. $data = $data ? json_encode($data, JSON_UNESCAPED_UNICODE) : null;
  42. } elseif ($data) {
  43. $action .= '?wt=json&' . http_build_query($data, null, '&');
  44. $data = null;
  45. }
  46. $url = $this->dsn . $this->core . '/' . $action;
  47. $ch = curl_init($url);
  48. if ($data) {
  49. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  50. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  51. }
  52. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  53. curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  54. 'Content-Type: application/json',
  55. 'Content-Length: ' . strlen($data))
  56. );
  57. $rs = curl_exec($ch);
  58. $rs = json_decode($rs, true);
  59. if (empty($rs) == false) {
  60. if (isset($rs['responseHeader']['status']) && 0 == $rs['responseHeader']['status']) {
  61. $rs = array('code' => 1, 'info' => '操作成功', 'data' => $rs);
  62. } else {
  63. $rs = array('code' => 0, 'info' => '操作失败', 'error' => $rs);
  64. }
  65. } else {
  66. if (0 < $redo) {
  67. $args = func_get_args();
  68. --$args[2];
  69. sleep(1);
  70. if ('cli' == PHP_SAPI && false !== strpos($action, 'update')) {
  71. echo "sleep\n";
  72. }
  73. return $this->post($args[0], $args[1], $args[2]);
  74. }
  75. $rs = array('code' => 0, 'info' => '网络错误,服务器繁忙');
  76. }
  77. if (('cli' == PHP_SAPI && false !== strpos($action, 'update')) || (isset($_GET['debug']) && 2 == $_GET['debug'])) {
  78. var_dump($url, $action, $data, $rs);
  79. }
  80. return $rs;
  81. }
  82. /**
  83. * 搜索数据
  84. * @param array $data
  85. * array(
  86. * 'fl' => '*,title', // 表示索引显示那些 field(*表示所有 field, score 是 solr 的一个匹配热度)
  87. * 'q.op' => 'AND', // 表示 q 中 查询语句的 各条件的逻辑操作 AND(与) OR(或)
  88. * 'start' => '0', // 开始返回条数
  89. * 'rows' => '16', // 返回多少条
  90. * 'hl' => 'true', // 是否高亮
  91. * 'hl.fl' => 'title', // 高亮 field
  92. * 'hl.snippets' => '3', // 不太清楚(反正是设置高亮 3 就可以了)
  93. * 'hl.simple.pre' => '<span style="color:#ff0000">', // 高亮前面的格式
  94. * 'hl.simple.post' => '</span>', // 高亮后面的格式
  95. * 'facet' => 'true', // 是否启动统计
  96. * 'facet.field' => 'sort', // 统计field
  97. * 'q' => '白兔', // 查询语句(类似 SQL) 相关详细的操作还需 lucene 的 query 语法
  98. * 'sort' => 'sort desc', // 排序
  99. * );
  100. * @return array
  101. */
  102. function select($data)
  103. {
  104. if (empty($data['q']) == true) {
  105. $result = array('code' => 0, 'info' => '关键词不能为空');
  106. } else {
  107. $method = 'select';
  108. $result = $this->post($method, $data);
  109. }
  110. return $result;
  111. }
  112. /**
  113. * 分词
  114. * @param array $data $data['q'] 关键词
  115. * @return array
  116. */
  117. function analysis($data)
  118. {
  119. if (empty($data['q']) == true) {
  120. $result = array('success' => 0, 'info' => '关键词不能为空');
  121. } else {
  122. $parame = array();
  123. $parame['q'] = urlencode($data['q']);
  124. $method = 'analysis/field';
  125. $result = $this->post($method, $parame);
  126. }
  127. return $result;
  128. }
  129. /**
  130. * 搜索建议
  131. * @param array $data $data['q'] 关键词
  132. * @return array
  133. */
  134. function suggest($data)
  135. {
  136. if (empty($data['q']) == true) {
  137. $result = array('success' => 0, 'info' => '关键词不能为空');
  138. } else {
  139. $parame = array();
  140. $parame['spellcheck.q'] = urlencode($data['q']);
  141. $parame['spellcheck'] = 'true';
  142. $method = 'suggest';
  143. $result = $this->post($method, $parame);
  144. }
  145. return $result;
  146. }
  147. /**
  148. * 相似搜索
  149. * @param array $data $data['q'] 关键词
  150. * @return array
  151. */
  152. function moreLike($data)
  153. {
  154. if (empty($data['q']) == true) {
  155. $result = array('success' => 0, 'info' => '关键词不能为空');
  156. } else {
  157. if (isset($data) == false) {
  158. $data = array();
  159. }
  160. $data['command'] = 'status';
  161. $method = 'dataimport';
  162. $result = $this->post($method, $data);
  163. }
  164. return $result;
  165. }
  166. /**
  167. * 全量导入索引
  168. * @param array $data
  169. * $data['clean'] 可选参数,为true时删除原有索引,false不删除,默认值为true
  170. * $data['entity'] 可选参数,document下面的标签(data-config.xml),使用这个参数可以有选择的执行一个或多个entity。如果不选择此参数那么所有的都会被运行
  171. * $data['commit'] 可选参数,选择是否在索引完成之后提交。默认为true
  172. * $data['optimize'] 可选参数,默认为true
  173. * $data['debug'] 可选参数,是否以调试模式运行,如果以调试模式运行,那么默认不会自动提交,请加参数“commit=true”
  174. * @return array
  175. */
  176. function fullImport($data = null)
  177. {
  178. if (isset($data) == false) {
  179. $data = array();
  180. }
  181. $data['command'] = 'full-import';
  182. $method = 'dataimport?';
  183. $result = $this->post($method, $data);
  184. return $result;
  185. }
  186. /**
  187. * 增量更新索引
  188. * @param array $data
  189. * @return array
  190. */
  191. function deltaImport($data = null)
  192. {
  193. if (!$data) {
  194. $data = array();
  195. }
  196. $data['command'] = 'delta-import';
  197. $method = 'dataimport';
  198. $result = $this->post($method, $data);
  199. return $result;
  200. }
  201. /**
  202. * 查看当前dataimport索引更新状态
  203. * @param array $data
  204. * @return array
  205. */
  206. function statusImport($data = null)
  207. {
  208. if (isset($data) == false) {
  209. $data = array();
  210. }
  211. $data['command'] = 'status';
  212. $method = 'dataimport';
  213. $result = $this->post($method, $data);
  214. return $result;
  215. }
  216. /**
  217. * 终止当前执行的dataimport任务
  218. * @param array $data
  219. * @return array
  220. */
  221. function abortImport($data = null)
  222. {
  223. if (isset($data) == false) {
  224. $data = array();
  225. }
  226. $data['command'] = 'abort';
  227. $method = 'dataimport';
  228. $result = $this->post($method, $data);
  229. return $result;
  230. }
  231. /**
  232. * 更新数据
  233. * @param array $datas 格式
  234. * 批量更新$datas=array(array('id'=>xx, 'app_name'=>array('set'=>'测试')))),id为索引主键字段,必须包含主键值
  235. * 单个更新$datas=array('id'=>xx, 'app_search_text'=>array('add'=>'测试'), 'look_count'=>array('inc'=>10))
  236. * set 设置或替当前值,null清空当前值
  237. * add 如果字段属性为multi-valued,添加一个值
  238. * inc 设置自增加值
  239. * @return array
  240. */
  241. function update($datas)
  242. {
  243. if (!$datas) {
  244. return false;
  245. }
  246. if (isset($datas[0]) == false || is_array($datas[0]) == false) {
  247. $datas = array($datas);
  248. }
  249. $method = 'update?commit=true';
  250. $result = $this->post($method, $datas);
  251. return $result;
  252. }
  253. /**
  254. * 删除数据
  255. * @param array $data $data=array('id'=>xx),id为索引主键字段
  256. * array('query'=>'xx:yy')
  257. * @return array
  258. */
  259. function delete($data)
  260. {
  261. if (!$data) {
  262. return false;
  263. }
  264. $data = array('delete' => $data);
  265. $method = 'update?commit=true';
  266. $result = $this->post($method, $data);
  267. return $result;
  268. }
  269. /**
  270. * 清空
  271. */
  272. function flush()
  273. {
  274. $this->delete(array('query' => '*:*'));
  275. }
  276. /**
  277. * 添加索引(不建议在程序中调用 ),注意:如果主键值相同,则会先删除旧索引,再添加新数据
  278. * @param array $datas
  279. * 批量添加$datas=array(array('id'=>xx, 'app_name'=>'测试测试'),id为索引主键字段,必须包含主键值
  280. * @return array
  281. */
  282. function add($datas)
  283. {
  284. if (!$datas) {
  285. return false;
  286. }
  287. // print_r($dates);
  288. if (isset($datas[0]) == false || is_array($datas[0]) == false) {
  289. $datas = array($datas);
  290. }
  291. $method = 'update?commit=true';
  292. $result = $this->post($method, $datas);
  293. return $result;
  294. }
  295. }
  296. // $q = $this->_POST("q","");
  297. // $data = array("fl"=>"id,title,url,tags","q.op"=>"AND","start"=>0,
  298. // "rows"=>20,"q"=> 'tags:"早餐"');
  299. // $solr = new Solr();
  300. // $res = $solr->select($data);
  301. // print_r($res);