-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
4070 lines (4035 loc) · 146 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://kingofzihua.github.io</id>
<title>kingofzihua</title>
<updated>2024-09-25T00:56:27.412Z</updated>
<generator>https://github.com/jpmonette/feed</generator>
<link rel="alternate" href="https://kingofzihua.github.io"/>
<link rel="self" href="https://kingofzihua.github.io/atom.xml"/>
<subtitle>我未曾见过一个早起、勤奋、谨慎、诚实的人整天抱怨的 — 富兰克林</subtitle>
<logo>https://kingofzihua.github.io/images/avatar.png</logo>
<icon>https://kingofzihua.github.io/favicon.ico</icon>
<rights>All rights reserved 2024, kingofzihua</rights>
<entry>
<title type="html"><![CDATA[Laravel 项目 伪静态分页处理]]></title>
<id>https://kingofzihua.github.io/post/laravel-xiang-mu-wei-jing-tai-fen-ye-chu-li/</id>
<link href="https://kingofzihua.github.io/post/laravel-xiang-mu-wei-jing-tai-fen-ye-chu-li/">
</link>
<updated>2019-12-31T01:54:47.000Z</updated>
<summary type="html"><![CDATA[<blockquote>
<p>手上有个Laravel 的项目,要求做伪静态处理,项目中使用了 Laravel 自带的分页组件,分页组件分页会在你的url 用 query 的方式做页码的传递,达不到伪静态的要求。</p>
</blockquote>
]]></summary>
<content type="html"><![CDATA[<blockquote>
<p>手上有个Laravel 的项目,要求做伪静态处理,项目中使用了 Laravel 自带的分页组件,分页组件分页会在你的url 用 query 的方式做页码的传递,达不到伪静态的要求。</p>
</blockquote>
<!-- more -->
<h2 id="想要的效果">想要的效果</h2>
<p>我们伪静态想要的效果大体是这样的:</p>
<pre><code class="language-php"> /software/3dmax/created_at/page-1.html
</code></pre>
<p>对应 Laravel 的路由是:</p>
<pre><code class="language-php">/software/{category}/{order}/page-{page}.html
</code></pre>
<p>因为laravel 路由本身是支持路由参数的,所以说 我们变量的获取是完全没有问题的,但是 Laravel 自带的分页组件会将你的 参数 用 query的方式做传递,所以,分页地址是下面这种</p>
<pre><code class="language-php"> /software/3dmax/created_at/page-1.html?category=3dmax&order=created_at&page=2
</code></pre>
<p>这不是我们需要的,所以我们需要对 Laravel 自带的分页组件进行修改。</p>
<h2 id="laravel-分页组件">Laravel 分页组件</h2>
<p> 在 Laravel 中我们如果需要分页,会调用 模型中的 <code>paginate</code> 方法,然后传递每页的页码。<code>paginate</code> 方法会调用 <code> Illuminate\Database\Concerns\BuildsQueries</code> 下的<code>paginator</code>方法,<code>paginator</code> 方法会构造一个 <code>Illuminate\Pagination\LengthAwarePaginator</code>的实例, <code>Illuminate\Pagination\LengthAwarePaginator</code> 会使用 <code>Illuminate\Pagination\AbstractPaginator</code> 中的<code>url</code>方法进行构造请求参数和url。<br>
现在我们找到生成url的地方了,我们需要做的就是在这里修改。</p>
<h2 id="重写分页组件">重写分页组件</h2>
<p>Laravel 中本身支持自定义分页组件,but我们做的不是自定义分页,我们需要对于方法进行重写。</p>
<h3 id="创建-lengthawarepaginator-类">创建 LengthAwarePaginator 类</h3>
<pre><code class="language-php">mkdir app/Pagination
touch app/Pagination/LengthAwarePaginator.php
</code></pre>
<p>文件app/Pagination/LengthAwarePaginator.php 内容:</p>
<pre><code><?php
namespace App\Pagination;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator;
class LengthAwarePaginator extends BasePaginator
{
}
</code></pre>
<h3 id="重写-url-方法">重写 url 方法</h3>
<p>首先 Laravel 自带的分页 会把路由里面的参数放到 query中,我们需要的是 参数还是放到地址中。</p>
<ul>
<li>获取到所有的query参数</li>
<li>判断需要分页的页面路由中是否有绑定的路由参数</li>
<li>如果没有的话,我们就走 Laravel 本身的分页</li>
<li>如果有的话,我们就通过路由和路由参数进行构建地址,并把它从query参数中剔除</li>
<li>判断下当前的query参数中是否还有参数,如果还有的话,我们就和之前一样。</li>
</ul>
<pre><code class="language-php">...
public function url($page)
{
if ($page <= 0) {
$page = 1;
}
$parameters = [$this->pageName => $page];
if (count($this->query) > 0) {
$parameters = array_merge($this->query, $parameters);
}
//判断的参数是否在 路由中 需要绑定的数据
$params = \request()->route()->parameters();
if (!empty($params)) {
foreach ($parameters as $key => $parameter) {
if (isset($params[$key])) {
$params[$key] = $parameter;
unset($parameters[$key]);
}
}
$path = route(\request()->route()->getAction('as'), $params);
} else {
$path = $this->path;
}
if (empty(Arr::query($parameters))) {
return $path . $this->buildFragment();
}
return $path
. (Str::contains($this->path, '?') ? '&' : '?')
. Arr::query($parameters)
. $this->buildFragment();
}
...
</code></pre>
<h2 id="使用自定义的分页组件">使用自定义的分页组件</h2>
<p>在 Laravel 中我们如果需要分页,会调用 模型中的 <code>paginate</code> 方法,但是<code>paginate</code>方法的定义在<code>Illuminate\Database\Eloquent\Builder</code>下,如果我们需要重写的话,会很麻烦,并且还有一个问题就是,并不是我们所有的分页都是需要伪静态的,比如我们用户中心的数据可能不太需要伪静态。所以我们需要一个可以手动设置的东西,Larave 模型中有一个 <a href="https://learnku.com/docs/laravel/5.8/eloquent/3931#4330c1">本地作用域</a>,我们可以写一个方法<code>staticPaginate</code>,当需要使用静态分页的时候,我们可以<code>Model->query()->staticPaginate();</code> 来调用,所需要的参数和 Laravel 自带的 <code>pageinage</code> 方法类似。</p>
<h3 id="公共的model-基类文件">公共的Model 基类文件</h3>
<p>Laravel项目中的 Model 我们一般不会直接继承<code>Illuminate\Database\Eloquent\Model</code> 我们一般都在 <code>app\Models</code> 目录定义一个 Model 基类,所有的模型都继承自 Model 基类,这并不是必须的,只是这样的话对于模型修改,或添加公共的方法比较方便。</p>
<h3 id="在模型中定义本地作用域">在模型中定义本地作用域</h3>
<p>你只需要拷贝 <code>Illuminate\Database\Eloquent\Builder</code>下的<code>paginate</code>方法的内容并修改<code>$this</code>的指向就可以了</p>
<pre><code class="language-php">
...
use Illuminate\Pagination\Paginator;
# Laravel 自带的。
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
...
/**
* 自定义静态分页
* @author kingofzihua
* @param Builder $builder
* @param int $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*
* @throws \InvalidArgumentException
*/
public function scopeStaticPaginate($builder, $perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
if (request('page')) {
request()->offsetSet('page', request('page'));
}
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $builder->getModel()->getPerPage();
$results = ($total = $builder->toBase()->getCountForPagination())
? $builder->forPage($page, $perPage)->get($columns)
: $builder->getModel()->newCollection();
return $this->paginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}
...
</code></pre>
<h3 id="替换自定义的分页组件">替换自定义的分页组件</h3>
<pre><code class="language-php">
# 替换下
use App\Pagination\LengthAwarePaginator;
...
/**
* Create a new length-aware paginator instance.
*
* @param \Illuminate\Support\Collection $items
* @param int $total
* @param int $perPage
* @param int $currentPage
* @param array $options
* @return \App\Pagination\LengthAwarePaginator
*/
protected function paginator($items, $total, $perPage, $currentPage, $options)
{
return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
'items', 'total', 'perPage', 'currentPage', 'options'
));
}
...
</code></pre>
<h2 id="在项目中使用静态分页组件">在项目中使用静态分页组件</h2>
<pre><code class="language-php">Model::query()->staticPaginate($pageSize);
</code></pre>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[文本处理三剑客之awk]]></title>
<id>https://kingofzihua.github.io/post/wen-ben-chu-li-san-jian-ke-zhi-awk/</id>
<link href="https://kingofzihua.github.io/post/wen-ben-chu-li-san-jian-ke-zhi-awk/">
</link>
<updated>2019-10-31T05:55:52.000Z</updated>
<summary type="html"><![CDATA[<blockquote>
<p>AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。 --- 百度百科</p>
</blockquote>
]]></summary>
<content type="html"><![CDATA[<blockquote>
<p>AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。 --- 百度百科</p>
</blockquote>
<!-- more -->
<h2 id="简介">简介</h2>
<p>AWK 是一个文本处理工具,通常用于处理数据并生成结果报告。</p>
<h3 id="awk的语法格式">awk的语法格式</h3>
<ul>
<li>第一种格式: <code>awk 'BEGIN{}pattern{commands}END{}' file_name</code></li>
<li>第二种格式: <code>standard output| awk 'BEGIN{}pattern{commands}END{}'</code></li>
</ul>
<h4 id="语法格式说明">语法格式说明</h4>
<table>
<thead>
<tr>
<th>语法格式</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr>
<td>BEGIN{}</td>
<td>正式处理数据之前执行</td>
</tr>
<tr>
<td>pattern</td>
<td>匹配模式</td>
</tr>
<tr>
<td>{commands}</td>
<td>处理命令,可能多行</td>
</tr>
<tr>
<td>END{}</td>
<td>处理完所有匹配数据后执行</td>
</tr>
</tbody>
</table>
<h3 id="awk中的内置变量">awk中的内置变量</h3>
<table>
<thead>
<tr>
<th style="text-align:left">内置变量</th>
<th style="text-align:center"></th>
<th style="text-align:left">含义</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">$0</td>
<td style="text-align:center"></td>
<td style="text-align:left">整行内容。</td>
</tr>
<tr>
<td style="text-align:left">$1-$n</td>
<td style="text-align:center"></td>
<td style="text-align:left">当前行的第1-n个字段。</td>
</tr>
<tr>
<td style="text-align:left">NF</td>
<td style="text-align:center">Number Field</td>
<td style="text-align:left">当前行的字段个数,也就是有多少列,$NF是最后一行。</td>
</tr>
<tr>
<td style="text-align:left">NR</td>
<td style="text-align:center">Number Row</td>
<td style="text-align:left">当前行的行号,从1开始计数。</td>
</tr>
<tr>
<td style="text-align:left">FNR</td>
<td style="text-align:center">File Number Row</td>
<td style="text-align:left">多文件处理时,每个文件行号单独计数,都是从0开始。</td>
</tr>
<tr>
<td style="text-align:left">FS</td>
<td style="text-align:center">Field Separator</td>
<td style="text-align:left">输入字段分隔符,不指定默认以空格或tab键分割。</td>
</tr>
<tr>
<td style="text-align:left">RS</td>
<td style="text-align:center">Row Separator</td>
<td style="text-align:left">输入行分隔符,默认回车换行。</td>
</tr>
<tr>
<td style="text-align:left">OFS</td>
<td style="text-align:center">Output Field Separator</td>
<td style="text-align:left">输出字段分隔符,默认为空格。</td>
</tr>
<tr>
<td style="text-align:left">ORS</td>
<td style="text-align:center">Output Row Separator</td>
<td style="text-align:left">输出行分隔符,默认为回车换行。</td>
</tr>
<tr>
<td style="text-align:left">FILENAME</td>
<td style="text-align:center"></td>
<td style="text-align:left">当前输入的文件名字。</td>
</tr>
<tr>
<td style="text-align:left">ARGC</td>
<td style="text-align:center"></td>
<td style="text-align:left">命令行参数个数。</td>
</tr>
<tr>
<td style="text-align:left">ARGV</td>
<td style="text-align:center"></td>
<td style="text-align:left">命令行参数数组。</td>
</tr>
</tbody>
</table>
<h3 id="commands-处理命令">commands 处理命令</h3>
<h4 id="printf"><code>printf</code></h4>
<h5 id="格式符说明">格式符说明</h5>
<table>
<thead>
<tr>
<th style="text-align:left">格式符</th>
<th style="text-align:left">含义</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">%s</td>
<td style="text-align:left">打印字符串</td>
</tr>
<tr>
<td style="text-align:left">%d</td>
<td style="text-align:left">打印十进制数</td>
</tr>
<tr>
<td style="text-align:left">%f</td>
<td style="text-align:left">打印一个浮点数</td>
</tr>
<tr>
<td style="text-align:left">%x</td>
<td style="text-align:left">打印十六进制数</td>
</tr>
<tr>
<td style="text-align:left">%o</td>
<td style="text-align:left">打印八进制数</td>
</tr>
<tr>
<td style="text-align:left">%e</td>
<td style="text-align:left">打印数字的科学计数法形式</td>
</tr>
<tr>
<td style="text-align:left">%c</td>
<td style="text-align:left">打印单个字符的ASCII码</td>
</tr>
</tbody>
</table>
<h5 id="修饰符说明">修饰符说明</h5>
<table>
<thead>
<tr>
<th style="text-align:left">修饰符</th>
<th style="text-align:left">含义</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">-</td>
<td style="text-align:left">左对齐</td>
</tr>
<tr>
<td style="text-align:left">+</td>
<td style="text-align:left">右对齐</td>
</tr>
<tr>
<td style="text-align:left">#</td>
<td style="text-align:left">显示8进制在前面加0,显示16进制在前面加0x。</td>
</tr>
</tbody>
</table>
<h3 id="正则表达式于操作符">正则表达式于操作符</h3>
<p>awk同sed一样也可以通过模式匹配来对输入的文本进行匹配处理。awk也支持大量的正则表达式模式,大部分与sed支持的元字符类似,而且正则表达式是玩转三剑客的必备工具。</p>
<h4 id="awk支持的正则表达式元字符">awk支持的正则表达式元字符</h4>
<table>
<thead>
<tr>
<th style="text-align:left">元字符</th>
<th style="text-align:left">功能</th>
<th style="text-align:left">示例</th>
<th style="text-align:left">解释</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">^</td>
<td style="text-align:left">字符串开头</td>
<td style="text-align:left">/^creditease/</td>
<td style="text-align:left">匹配所有以 creditease 开头的字符串</td>
</tr>
<tr>
<td style="text-align:left">$</td>
<td style="text-align:left">字符串的结尾</td>
<td style="text-align:left">/creditease$/</td>
<td style="text-align:left">匹配所有以 creditease 结尾的字符串</td>
</tr>
<tr>
<td style="text-align:left">.</td>
<td style="text-align:left">匹配任意单个字符(包括回车符)</td>
<td style="text-align:left">/c..1/</td>
<td style="text-align:left">匹配字母c,然后两个任意字符,再以1结尾的行, 比如ckkl</td>
</tr>
<tr>
<td style="text-align:left">*</td>
<td style="text-align:left">重复0个或多个字符</td>
<td style="text-align:left">/a*cool/</td>
<td style="text-align:left">匹配a 和cool 中间间隔0个或多个字符</td>
</tr>
<tr>
<td style="text-align:left">+</td>
<td style="text-align:left">重复前一个字符一次或一次以上</td>
<td style="text-align:left">/a+b/</td>
<td style="text-align:left">匹配一个或多个a加b的行</td>
</tr>
<tr>
<td style="text-align:left">?</td>
<td style="text-align:left">匹配0个或一个前导字符</td>
<td style="text-align:left">/a?b/</td>
<td style="text-align:left">匹配b或者ab的行</td>
</tr>
<tr>
<td style="text-align:left">[]</td>
<td style="text-align:left">匹配指定字符组内的任一个字符</td>
<td style="text-align:left">/^[abc]/</td>
<td style="text-align:left">匹配以字母a或b或c开头的行</td>
</tr>
<tr>
<td style="text-align:left">[^]</td>
<td style="text-align:left">匹配不再指定字符组内的任一个字符</td>
<td style="text-align:left">/<sup>[</sup>abc]/</td>
<td style="text-align:left">匹配不以字母a或b或c开头的行</td>
</tr>
<tr>
<td style="text-align:left">()</td>
<td style="text-align:left">子表达式组合</td>
<td style="text-align:left">/(cool)+/</td>
<td style="text-align:left">表示一个或多个cool组合,当有一些字符需要组合时,使用括号括起来</td>
</tr>
<tr>
<td style="text-align:left">|</td>
<td style="text-align:left">或者的意思</td>
<td style="text-align:left">/(cool)|B/</td>
<td style="text-align:left">匹配cool或者字母B的行</td>
</tr>
</tbody>
</table>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Elasticsearch Query DSL - 复合查询]]></title>
<id>https://kingofzihua.github.io/post/elasticsearch-query-dsl-compound-queries/</id>
<link href="https://kingofzihua.github.io/post/elasticsearch-query-dsl-compound-queries/">
</link>
<updated>2019-09-16T06:12:04.000Z</updated>
<summary type="html"><![CDATA[<blockquote>
<p>复合查询包括其他复合查询或叶查询,可以组合其结果和分数,更改其行为,或者从查询切换到筛选上下文。</p>
</blockquote>
]]></summary>
<content type="html"><![CDATA[<blockquote>
<p>复合查询包括其他复合查询或叶查询,可以组合其结果和分数,更改其行为,或者从查询切换到筛选上下文。</p>
</blockquote>
<!-- more -->
<h2 id="bool-query-布尔查询">Bool Query 布尔查询</h2>
<ul>
<li>一个 bool 查询 ,是一个或者多个查询子句的组合
<ul>
<li>总共包括4中子句。其中两种会影响算分,2中不影响算分</li>
</ul>
</li>
<li>相关性并不只是全文检索的专利。也适用于 yes|no的子句,匹配的子句越多,相关性评越高。如果多条子查询语句被合并为一跳复合查询语句,比如bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align:center">类型</th>
<th style="text-align:center">匹配</th>
<th style="text-align:center">算分</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">must</td>
<td style="text-align:center">必须匹配</td>
<td style="text-align:center">贡献算分</td>
</tr>
<tr>
<td style="text-align:center">should</td>
<td style="text-align:center">选择性匹配</td>
<td style="text-align:center">贡献算分</td>
</tr>
<tr>
<td style="text-align:center">must_not</td>
<td style="text-align:center">Filter Context <br> 必须不能匹配</td>
<td style="text-align:center">不贡献算分</td>
</tr>
<tr>
<td style="text-align:center">filter</td>
<td style="text-align:center">Filter Context <br> 必须匹配</td>
<td style="text-align:center">不贡献算分</td>
</tr>
</tbody>
</table>
<p><strong>Filter Context -不影响算分</strong></p>
<h3 id="请求示例">请求示例</h3>
<h4 id="准备数据">准备数据</h4>
<pre><code>POST /news/_bulk
{"index":{"_id":1}}
{"content":"Apple Mac"}
{"index":{"_id":2}}
{"content":"Apple iPad"}
{"index":{"_id":3}}
{"content":"Apple employee like Apple Pie and Apple Juice"}
</code></pre>
<h4 id="must-查询">Must 查询</h4>
<p>查询包含apple的内容<br>
请求</p>
<pre><code>POST news/_search
{
"query":{
"bool": {
"must": [
{"match": {"content": "apple"}}
]
}
}
}
</code></pre>
<p>返回结果:</p>
<pre><code>{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.17280532,
"hits" : [
{
"_index" : "news",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.17280532,
"_source" : {
"content" : "Apple employee like Apple Pie and Apple Juice"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple Mac"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple iPad"
}
}
]
}
}
</code></pre>
<h4 id="must-not-查询">Must Not 查询</h4>
<p>查询包含apple的内容 但是不包含 pie<br>
请求</p>
<pre><code>POST news/_search
{
"query":{
"bool": {
"must": [
{"match": {"content": "apple"}}
],
"must_not": [
{"match": {"content": "pie"}}
]
}
}
}
</code></pre>
<p>返回结果:</p>
<pre><code>{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.16786805,
"hits" : [
{
"_index" : "news",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple Mac"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple iPad"
}
}
]
}
}
</code></pre>
<h3 id="bool-嵌套">Bool 嵌套</h3>
<figure data-type="image" tabindex="1"><img src="https://kingofzihua.github.io/post-images/1568255247856.png" alt="" loading="lazy"></figure>
<h4 id="查询语句的结构会对相关度算分产生影响">查询语句的结构,会对相关度算分产生影响</h4>
<ul>
<li>同一层级下对竞争字段,具有相同对权重</li>
<li>通过嵌套bool查询,可以改变对算分对影响</li>
</ul>
<figure data-type="image" tabindex="2"><img src="https://kingofzihua.github.io/post-images/1568255536825.png" alt="" loading="lazy"></figure>
<h4 id="查询语法">查询语法</h4>
<ul>
<li>子查询可以任意顺序出现</li>
<li>可以嵌套多个查询</li>
<li>如果你的bool查询中,没有must条件,should中必须至少满足一条查询</li>
</ul>
<figure data-type="image" tabindex="3"><img src="https://kingofzihua.github.io/post-images/1568254527196.jpg" alt="" loading="lazy"></figure>
<h2 id="boosting-相关性提升查询">Boosting 相关性提升查询</h2>
<ul>
<li>Boosting 是控制相关度的一种手段</li>
<li>参数 boost 的含义
<ul>
<li>当 boost > 1,打分的相关度相对性提升</li>
<li>当 0 < boost < 1,打分的权重相对性降低</li>
<li>当 boost < 0 时,贡献负分</li>
</ul>
</li>
</ul>
<h3 id="请求示例-2">请求示例</h3>
<h4 id="准备测试数据">准备测试数据</h4>
<pre><code>POST /blogs/_bulk
{"index":{"_id":1}}
{"title":"Apple iPad","content":"Apple iPad,Apple iPad"}
{"index":{"_id":2}}
{"title":"Apple iPad,Apple iPad","content":"Apple iPad"}
</code></pre>
<h4 id="测试">测试</h4>
<pre><code>POST news/_search
{
"query":{
"boosting": {
"positive": { //提升
"match": {
"content": "apple"
}
},
"negative": { //降低
"match": {
"content": "pie"
}
},
"negative_boost": 0.5 //降低的分数
}
}
}
</code></pre>
<p>返回结果:</p>
<pre><code>{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 0.16786805,
"hits" : [
{
"_index" : "news",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple Mac"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.16786805,
"_source" : {
"content" : "Apple iPad"
}
},
{
"_index" : "news",
"_type" : "_doc",
"_id" : "3",
"_score" : 0.08640266,
"_source" : {
"content" : "Apple employee like Apple Pie and Apple Juice"
}
}
]
}
}
</code></pre>
<p> 可以把<code>negative_boost</code> 改成 <code>1</code> 对比查看效果。原本来说文档3中 <code>apple </code>出现的频率高,算分高,通过降低相关性,调整了返回结果的算分。</p>
<h3 id="顶级参数">顶级参数</h3>
<p> <code>positive</code>:(必需,查询对象)您希望运行的查询。任何返回的文档必须与此查询匹配。<br>
<code>negative</code>:(必需,查询对象)用于降低匹配文档的<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html#relevance-scores">相关性得分</a>的查询。<br>
如果返回的文档与<code>positive</code>查询和此查询匹配,则 <code>boosting</code>查询将计算文档的最终相关性分数,如下所示:</p>
<ul>
<li>从positive查询中获取原始相关性分数。</li>
<li>将得分乘以该negative_boost值。</li>
</ul>
<p> <code>negative_boost</code>:(必需,浮动)之间的浮点数0和1.0用于降低<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html#relevance-scores">相关性得分</a>的匹配的文件 negative的查询。</p>
<h2 id="constant-score-查询">Constant Score 查询</h2>
<ul>
<li>将Query 转成Filter,忽略 TF-IDF计算,避免相关性算分的开销</li>
<li>Filter 可以有效利用缓存</li>
</ul>
<h3 id="请求示例-3">请求示例</h3>
<pre><code>POST news/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"content": "apple"
}
},
"boost": 1
}
}
}
</code></pre>
<h3 id="顶级参数-2">顶级参数</h3>
<p><code>filter</code> :<br>
(必需,查询对象)要运行的<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-dsl-bool-query.html">筛选查询</a>。任何返回的文档必须与此查询匹配。<br>
过滤查询不会计算<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html#relevance-scores">相关性分数</a> 。为了加快性能,Elasticsearch会自动缓存经常使用的过滤器查询。</p>
<p><code>boost</code> :<br>
(可选,浮点)浮点数用作匹配查询的每个文档的常量 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html#relevance-scores">相关性分数</a> filter。默认为1.0。</p>
<h2 id="disjunction-max-查询">Disjunction Max 查询</h2>
<ul>
<li>将任何与任一查询匹配的文档作为结果返回</li>
<li>采用字段上最匹配的评分最终评分返回</li>
</ul>
<h3 id="请求示例-4">请求示例</h3>
<h4 id="准备测试数据-2">准备测试数据</h4>
<pre><code>PUT blogs/_bulk
{"index":{"_id":1}}
{"title":"Quick brown rabbits","body":"Brown rabbits are commonly seen."}
{"index":{"_id":2}}
{"title":"Keeping pets healthy","body":"My quick brown fox eats rabbits on a regular basis."}
</code></pre>
<h4 id="使用-bool-查询">使用 bool 查询</h4>
<p>请求:</p>
<pre><code>POST blogs/_search
{
"query": {
"bool": {
"should": [
{"match": {"title": "Brown fox"}},
{"match": {"body": "Brown fox"}}
]
}
}
}
</code></pre>
<p>返回结果:</p>
<pre><code>{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.90425634,
"hits" : [
{
"_index" : "blogs",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.90425634,
"_source" : {
"title" : "Quick brown rabbits",
"body" : "Brown rabbits are commonly seen."
}
},
{
"_index" : "blogs",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.77041256,
"_source" : {
"title" : "Keeping pets healthy",
"body" : "My quick brown fox eats rabbits on a regular basis."
}
}
]
}
}
</code></pre>
<h4 id="使用-dis_max-查询-disjunction-max-query">使用 dis_max 查询 (Disjunction Max Query)</h4>
<p>请求:</p>
<pre><code>POST blogs/_search
{
"query": {
"dis_max": {
"queries": [
{"match": {"title": "Brown fox"}},
{"match": {"body": "Brown fox"}}
]
}
}
}
</code></pre>
<p>返回结果:</p>
<pre><code>{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.77041256,
"hits" : [
{
"_index" : "blogs",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.77041256,
"_source" : {
"title" : "Keeping pets healthy",
"body" : "My quick brown fox eats rabbits on a regular basis."
}
},
{
"_index" : "blogs",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.6931472,
"_source" : {
"title" : "Quick brown rabbits",
"body" : "Brown rabbits are commonly seen."
}
}
]
}
}
</code></pre>
<h3 id="顶级参数-3">顶级参数</h3>
<p><code>queries</code> :<br>
(必需,查询对象数组)包含一个或多个查询子句。返回的文档必须与这些查询中的<strong>一个或多个匹配</strong>。如果文档与多个查询匹配,则Elasticsearch使用最高<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/query-filter-context.html">相关性分数</a>。<br>
<code>tie_breaker</code> :<br>
(可选,浮动)之间的浮动点数目0和1.0用于提高相关分数的匹配多个查询子句文档。默认为0.0。</p>
<h3 id="tie-breaker-参数调整评分">Tie Breaker 参数调整评分</h3>
<p>Tier Breaker 是一个介于0-1之间的浮点数。 0代表使用最佳匹配,1代表所有语句同等重要。</p>
<ul>
<li>获得最佳匹配语句的评分 <code>_score</code></li>
<li>将其他匹配语句的评分与 <code>tie_breaker</code> 相乘</li>
<li>将最高分数添加到相乘的分数中。</li>
</ul>
<p> 如果该tie_breaker值大于0.0,则所有匹配子句都计数,但得分最高的子句最多。</p>
<h2 id="function-score-查询">Function Score 查询</h2>
<p>...</p>
<hr>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/compound-queries.html">Elasticsearch文档:Compound-queries</a></li>
<li><a href="https://time.geekbang.org/course/intro/197">极客时间:Elasticsearch核心技术与实战</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Elasticsearch Query DSL - 术语查询 ]]></title>
<id>https://kingofzihua.github.io/post/elasticsearch-query-dsl-term-level-querie/</id>
<link href="https://kingofzihua.github.io/post/elasticsearch-query-dsl-term-level-querie/">
</link>
<updated>2019-09-12T06:41:19.000Z</updated>
<summary type="html"><![CDATA[<blockquote>
<p>Term Level(术语) 查询操作的是存储在反向索引(倒排索引)中的准确词根,这些查询通常用于结构化数据,如数字、日期和枚举,而不是全文字段,无需进行分析(分词),Term Level查询类似于关系型数据库的(where条件过滤)。</p>
</blockquote>
]]></summary>
<content type="html"><![CDATA[<blockquote>
<p>Term Level(术语) 查询操作的是存储在反向索引(倒排索引)中的准确词根,这些查询通常用于结构化数据,如数字、日期和枚举,而不是全文字段,无需进行分析(分词),Term Level查询类似于关系型数据库的(where条件过滤)。</p>
</blockquote>
<!-- more -->
<h2 id="exists-存在-非空查询">Exists (存在) 非空查询</h2>
<p> 返回在提供的字段中包含null或[]以外的值的文档。</p>
<h3 id="请求实例">请求实例</h3>
<pre><code>
POST /moulds/_search
{
"query": {
"exists": {
"field": "deleted_at"
}
}
}
</code></pre>
<h3 id="顶级参数">顶级参数</h3>
<p> <code>field</code>: ( 必填 , 字符串 ) 所要搜索的字段名称<br>
要返回文档,此字段必须存在且包含除<code>null</code> 或者 <code>[]</code> 以外的的值,这些值可包括:</p>
<ul>
<li>空的字符串,例如<code>""</code> 或 <code>"-"</code></li>
<li>包含 <code>null</code> 和其他值的数组,例如<code> [null,"foo"]</code></li>
<li>自定义 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.2/null-value.html">null-value</a> ,在字段映射中定义</li>
</ul>
<h3 id="备注">备注</h3>
<h4 id="查找具有空值的文档">查找具有空值的文档</h4>
<p> 为了找到只包含文件<code>null</code>值或<code>[]</code>在所提供的字段,使用 <code>must_not</code> 布尔查询与<code>exists</code> 查询</p>
<pre><code>
GET moulds/_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "deleted_at"
}
}
}
}
}
</code></pre>
<h2 id="fuzzy-模糊查询">Fuzzy 模糊查询</h2>
<p> 返回包含与搜索词类似的词的文档。 由<a href="https://zh.wikipedia.org/wiki/%E8%90%8A%E6%96%87%E6%96%AF%E5%9D%A6%E8%B7%9D%E9%9B%A2">莱文斯坦距离</a>测量。<br>
编辑距离是将一个术语转换为另一个术语所需的单个字符更改的数量。这些变化包括:</p>
<ul>
<li>改变一个字符 (<strong>b</strong>ox → <strong>f</strong>ox)</li>
<li>删除一个字符 (<strong>b</strong>lack → lack)</li>
<li>插入一个字符 (sic → sic<strong>k</strong>)</li>
<li>转置两个相邻的字符 (<strong>ac</strong>t → <strong>ca</strong>t)</li>
</ul>
<h3 id="请求示例">请求示例</h3>
<h4 id="简单的例子">简单的例子</h4>
<pre><code>GET /_search
{
"query": {
"fuzzy": {
"user": {
"value": "ki"
}
}
}
}
</code></pre>
<h4 id="使用高级参数的例子">使用高级参数的例子</h4>
<pre><code>GET /_search
{
"query": {
"fuzzy": {
"user": {
"value": "ki",
"fuzziness": "AUTO",