SubBuilder.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <?php
  2. namespace App\Search\Builders;
  3. use Closure;
  4. class SubBuilder
  5. {
  6. public $wheres = [];
  7. /**
  8. * @param string|Closure $field
  9. * @param mixed $value
  10. * @return $this
  11. */
  12. public function where($field, $value = null)
  13. {
  14. if ($field instanceof Closure) {
  15. $shouldBuilder=new SubBuilder();
  16. call_user_func($field, $shouldBuilder);
  17. $this->wheres['must']['query'][]=$shouldBuilder->getQueryData();
  18. return $this;
  19. }
  20. $this->wheres['must']['where'][]=[
  21. 'field'=>$field,
  22. 'value'=>$value
  23. ];
  24. return $this;
  25. }
  26. /**
  27. * @param string|Closure $field
  28. * @param string|int $value
  29. * @return $this
  30. */
  31. public function whereNot($field, $value = null)
  32. {
  33. if ($field instanceof Closure) {
  34. $shouldBuilder=new SubBuilder();
  35. call_user_func($field, $shouldBuilder);
  36. $this->wheres['must_not']['query'][]=$shouldBuilder->getQueryData();
  37. return $this;
  38. }
  39. $this->wheres['must_not']['where'][]=[
  40. 'field'=>$field,
  41. 'value'=>$value
  42. ];
  43. return $this;
  44. }
  45. /**
  46. * @param string|Closure $field
  47. * @param string|int $value
  48. * @return $this
  49. */
  50. public function whereOr($field, $value = null)
  51. {
  52. if ($field instanceof Closure) {
  53. $shouldBuilder=new SubBuilder();
  54. call_user_func($field, $shouldBuilder);
  55. $this->wheres['should']['query'][]=$shouldBuilder->getQueryData();
  56. return $this;
  57. }
  58. $this->wheres['should']['where'][]=[
  59. 'field'=>$field,
  60. 'value'=>$value
  61. ];
  62. return $this;
  63. }
  64. /**
  65. * @param string $field
  66. * @param array $value
  67. * @param bool $isKeyword
  68. * @return $this
  69. */
  70. public function whereIn(string $field, array $value, $isKeyword = true)
  71. {
  72. if ($isKeyword) {
  73. $this->wheres['in']['terms'][]=[
  74. 'field'=>$field,
  75. 'value'=>$value
  76. ];
  77. } else {
  78. $this->wheres['in']['phrase'][]=[
  79. 'field'=>$field,
  80. 'value'=>$value
  81. ];
  82. }
  83. return $this;
  84. }
  85. /**
  86. * @param string $field
  87. * @param array $value
  88. * @param bool $isKeyword
  89. * @return $this
  90. */
  91. public function whereOrIn(string $field, array $value, $isKeyword = true)
  92. {
  93. if ($isKeyword) {
  94. $this->wheres['should_in']['terms'][]=[
  95. 'field'=>$field,
  96. 'value'=>$value
  97. ];
  98. } else {
  99. $this->wheres['should_in']['phrase'][]=[
  100. 'field'=>$field,
  101. 'value'=>$value
  102. ];
  103. }
  104. return $this;
  105. }
  106. /**
  107. * @param string $field
  108. * @param array $value
  109. * @param bool $isKeyword
  110. * @return $this
  111. */
  112. public function whereNotIn(string $field, array $value, $isKeyword = true)
  113. {
  114. if ($isKeyword) {
  115. $this->wheres['not_in']['terms'][]=[
  116. 'field'=>$field,
  117. 'value'=>$value
  118. ];
  119. } else {
  120. $this->wheres['not_in']['phrase'][]=[
  121. 'field'=>$field,
  122. 'value'=>$value
  123. ];
  124. }
  125. return $this;
  126. }
  127. /**
  128. * @param string $field
  129. * @param null $min
  130. * @param null $max
  131. * @param bool $equal
  132. * @return $this
  133. */
  134. public function whereRange(string $field, $min = null, $max = null, $equal = true)
  135. {
  136. $equal=$equal?'e':'';
  137. $range=[];
  138. if (!is_null($min)) {
  139. $range['gt'.$equal]=$min;
  140. }
  141. if (!is_null($max)) {
  142. $range['lt'.$equal]=$max;
  143. }
  144. $this->wheres['must']['range'][]=[
  145. 'field'=>$field,
  146. 'value'=>$range
  147. ];
  148. return $this;
  149. }
  150. /**
  151. * @param string $field
  152. * @param null $min
  153. * @param null $max
  154. * @param bool $equal
  155. * @return $this
  156. */
  157. public function whereOrRange(string $field, $min = null, $max = null, $equal = true)
  158. {
  159. $equal=$equal?'e':'';
  160. $range=[];
  161. if (!is_null($min)) {
  162. $range['gt'.$equal]=$min;
  163. }
  164. if (!is_null($max)) {
  165. $range['lt'.$equal]=$max;
  166. }
  167. $this->wheres['should']['range'][]=[
  168. 'field'=>$field,
  169. 'value'=>$range
  170. ];
  171. return $this;
  172. }
  173. /**
  174. * @param string $field
  175. * @param null $min
  176. * @param null $max
  177. * @param bool $equal
  178. * @return $this
  179. */
  180. public function whereNotRange(string $field, $min = null, $max = null, $equal = true)
  181. {
  182. $equal=$equal?'e':'';
  183. $range=[];
  184. if (!is_null($min)) {
  185. $range['gt'.$equal]=$min;
  186. }
  187. if (!is_null($max)) {
  188. $range['lt'.$equal]=$max;
  189. }
  190. $this->wheres['must_not']['range'][]=[
  191. 'field'=>$field,
  192. 'value'=>$range
  193. ];
  194. return $this;
  195. }
  196. public function getQueryData()
  197. {
  198. $query = [];
  199. $must_data = [];
  200. $must_not_data = [];
  201. $should_data = [];
  202. if (empty($this->wheres)) {
  203. return $query;
  204. }
  205. //处理and逻辑
  206. if (isset($this->wheres['must'])) {
  207. if (isset($this->wheres['must']['where'])) {
  208. foreach ($this->wheres['must']['where'] as $value) {
  209. $must_data[]=[
  210. "match_phrase"=>[$value['field'] => $value['value']]
  211. ];
  212. }
  213. }
  214. if (isset($this->wheres['must']['range'])) {
  215. foreach ($this->wheres['must']['range'] as $value) {
  216. $must_data[]=[
  217. "range"=>[$value['field'] => $value['value']]
  218. ];
  219. }
  220. }
  221. }
  222. if (isset($this->wheres['in'])) {
  223. if (isset($this->wheres['in']['terms'])) {
  224. foreach ($this->wheres['in']['terms'] as $value) {
  225. $must_data[]=[
  226. "terms"=>[$value['field'] => $value['value']]
  227. ];
  228. }
  229. }
  230. if (isset($this->wheres['in']['phrase'])) {
  231. $sub_data = [];
  232. foreach ($this->wheres['in']['phrase'] as $value) {
  233. foreach ($value['value'] as $v) {
  234. $sub_data[]=[
  235. "match_phrase"=>[$value['field'] => $v]
  236. ];
  237. }
  238. }
  239. $must_data[] = ['bool' => ['should'=>$sub_data]];
  240. }
  241. }
  242. if (isset($this->wheres['must']['query'])) {
  243. $must_data=array_merge($must_data, $this->wheres['must']['query']);
  244. }
  245. //处理not逻辑
  246. if (isset($this->wheres['must_not'])) {
  247. if (isset($this->wheres['must_not']['where'])) {
  248. foreach ($this->wheres['must_not']['where'] as $value) {
  249. $must_not_data[]=[
  250. "match_phrase"=>[$value['field'] => $value['value']]
  251. ];
  252. }
  253. }
  254. if (isset($this->wheres['must_not']['range'])) {
  255. foreach ($this->wheres['must_not']['range'] as $value) {
  256. $must_not_data[]=[
  257. "range"=>[$value['field'] => $value['value']]
  258. ];
  259. }
  260. }
  261. }
  262. if (isset($this->wheres['not_in'])) {
  263. if (isset($this->wheres['not_in']['terms'])) {
  264. foreach ($this->wheres['not_in']['terms'] as $value) {
  265. $must_not_data[]=[
  266. "terms"=>[$value['field'] => $value['value']]
  267. ];
  268. }
  269. }
  270. if (isset($this->wheres['not_in']['phrase'])) {
  271. foreach ($this->wheres['not_in']['phrase'] as $value) {
  272. foreach ($value['value'] as $v) {
  273. $must_not_data[]=[
  274. "match_phrase"=>[$value['field'] => $v]
  275. ];
  276. }
  277. }
  278. }
  279. }
  280. if (isset($this->wheres['must_not']['query'])) {
  281. $must_not_data=array_merge($must_not_data, $this->wheres['must_not']['query']);
  282. }
  283. //处理or逻辑
  284. if (isset($this->wheres['should'])) {
  285. if (isset($this->wheres['should']['where'])) {
  286. foreach ($this->wheres['should']['where'] as $value) {
  287. $should_data[]=[
  288. "match_phrase"=>[$value['field'] => $value['value']]
  289. ];
  290. }
  291. }
  292. if (isset($this->wheres['should']['range'])) {
  293. foreach ($this->wheres['should']['range'] as $value) {
  294. $should_data[]=[
  295. "range"=>[$value['field'] => $value['value']]
  296. ];
  297. }
  298. }
  299. }
  300. if (isset($this->wheres['should_in'])) {
  301. if (isset($this->wheres['should_in']['terms'])) {
  302. foreach ($this->wheres['should_in']['terms'] as $value) {
  303. $should_data[]=[
  304. "terms"=>[$value['field'] => $value['value']]
  305. ];
  306. }
  307. }
  308. if (isset($this->wheres['should_in']['phrase'])) {
  309. foreach ($this->wheres['should_in']['phrase'] as $value) {
  310. foreach ($value['value'] as $v) {
  311. $should_data[]=[
  312. "match_phrase"=>[$value['field'] => $v]
  313. ];
  314. }
  315. }
  316. }
  317. }
  318. if (isset($this->wheres['should']['query'])) {
  319. $should_data=array_merge($should_data, $this->wheres['should']['query']);
  320. }
  321. if ($must_data) {
  322. $query['must']=$must_data;
  323. }
  324. if ($must_not_data) {
  325. $query['must_not']=$must_not_data;
  326. }
  327. if ($should_data) {
  328. $query['should']=$should_data;
  329. }
  330. return ['bool'=>$query];
  331. }
  332. }