Playbook中jinja2模板的使用

本章主要介绍playbook中如何使用jinja2模板

  • 什么是jinja2模板
  • 在jinja2模板文件中写if判断语句
  • 在jinja2模板文件在写for循环语句
  • handlers的使用

可以使用copy模块把本地的一个文件拷贝到远端机器,下面再次复习一下

本章实验都在demo4文件夹下操作,跟之前一样把ansible.cf和hosts文件拷贝进去

[jin@rhel801 ~]$ cd demo4/
[jin@rhel801 demo4]$ ls
ansible.cfg  hosts
[jin@rhel801 demo4]$

练习1:用copy拷贝一个文件到db主机组

有一个文件aa.txt,内容如下

[jin@rhel801 demo4]$ cat aa.txt 
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的 IP 地址是: {{ansible_default_ipv4.address}}
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
[jin@rhel801 demo4]$

这个文件中包含一个 fact变量 ansible_default_ipv4.address

写一个 playbook,内容如下

[jin@rhel801 demo4]$ cat 1.yml 
---
- hosts: db
  tasks:
  - name: 拷贝一个文件到远端主机
    copy: src=aa.txt dest=/opt/aa.txt
[jin@rhel801 demo4]$

运行此playbook

[jin@rhel801 demo4]$ ansible-playbook 1.yml 

PLAY [db] **********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]
ok: [rhel803]

TASK [拷贝一个文件到远端主机] *************************************************************
ok: [rhel802]
changed: [rhel803]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rhel803                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

现在已经把本地的aa.,txt拷贝到rhel802和 rhel803的/opt目录中了。下面查看这两台主机 上 /opt/aa.txt的内容

[jin@rhel801 demo4]$ ansible db -m shell -a "cat /opt/aa.txt"
rhel802 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的 IP 地址是: {{ansible_default_ipv4.address}}
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
rhel803 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的 IP 地址是: {{ansible_default_ipv4.address}}
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
[jin@rhel801 demo4]$ 

可以看到,当用copy拷贝一个文件到远端机器时,如果这个文件中有变量,拷贝过去的文件中的变量并不会变成具体的值

如果希望文件考别过去之后,文件中的变量变成具体的值,那么就不能使用copy模块,而是要使用template模块了

练习2:修改1.yml的内容如下

[jin@rhel801 demo4]$ cat 1.yml 
---
- hosts: db
  tasks:
  - name: 拷贝一个文件到远端主机
    template: src=aa.txt dest=/opt/aa.txt
[jin@rhel801 demo4]$

与刚才相比,只是把copy换成了template。template模块的用法与copy模块一致,所以这里选项并没有变。运行此 playbook

[jin@rhel801 demo4]$ ansible-playbook 1.yml 

PLAY [db] **********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]
ok: [rhel803]

TASK [拷贝一个文件到远端主机] *************************************************************
changed: [rhel802]
changed: [rhel803]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rhel803                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$ 

再次查看两台主机上/opt/aa.txt的内容

[jin@rhel801 demo4]$ ansible db -m shell -a "cat /opt/aa.txt"
rhel802 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的 IP 地址是: 192.168.161.17
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
rhel803 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的 IP 地址是: 192.168.161.18
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
[jin@rhel801 demo4]$

可以看到,通过template拷贝含有变量的文件时,拷贝到远端机器之后,文件中的变量 会变成具体的值

这个通过template拷贝的、含有变量的文件我们称为jinja2模板,jinja2模板文件的后缀 一般使用j2,这不是必需的,但是建议使用j2作为后缀

所以,需要修改aa.txt的文件为aa.j2

[jin@rhel801 demo4]$ mv aa.txt aa.j2

同时修改1.yml中对应的内容

[jin@rhel801 demo4]$ cat 1.yml 
---
- hosts: db
  tasks:
  - name: 拷贝一个文件到远端主机
    template: src=aa.j2 dest=/opt/aa.txt
[jin@rhel801 demo4]$

这里如果jinja2模板文件没有写路径,例如,例子中 src=aa.j2的aa.j2没有写路径,则优先到当前目录的templates 中找aa.j2,如果没有,则到当前目录中找aa.j2

练习3:验证,命令如下

[jin@rhel801 demo4]$ mkdir templates

在templates目录中创建aa.j2,内容如下

[jin@rhel801 templates]$ cat aa.j2 
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的主机名是: {{ansible_fqdn}}
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+

[jin@rhel801 templates]$

这样我们就有两个aa.j2了,还有一个是当前目录下的aa.j2

再次运行此playbook

[jin@rhel801 demo4]$ ansible-playbook 1.yml

查看两台主机上/opt/aa.txt 的内容

[jin@rhel801 demo4]$ ansible db -m shell -a "cat /opt/aa.txt"
rhel803 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的主机名是: rhel803
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
rhel802 | CHANGED | rc=0 >>
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| 我的主机名是: rhel802
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
[jin@rhel801 demo4]$

里可以看到显示的主机名,所以是 templates目录中的aa.j2生效了

1.1 if判断

在jinja2模板文件中,我们也是可以使用if判断语句的,语法格式如下

1 {% if 判断1 %}
2 内容1
3 {% elif 判断2 %}
4 内容2
5 ...多个elif...
6 {% else %}
7 内容3
8 {% endif %}

注意

(1)“%”两边有没有空格都可以,不过所有的“%”前后空格要保持一致,即要有都有,要没有都没有

(2)if和elif中的内容如果太长了,可以另起一行写

如果判断1成立,则打印内容1,后面的条件不再判断,直接跳转到endif后面的内容;如果判断1不成立,则执行elif后面的判断2,如果成立则打印内容2,后面的条件不再判断,直接跳转到endif后面的内容。以此类推,如果所有的f和elif都不成立,则打印else中的内容

(3)elif和 else不是必需的

练习:写一个 jinja2模板文件,内容如下

[jin@rhel801 templates]$ cat bb.j2 
1111
{% if ansible_fqdn=="rhel802" %}
  {{ansible_fqdn}}
{% else %}
  aaaa
{% endif %}
  3333
[jin@rhel801 templates]$

这里jinja2模板所生成的文件一共会产生3行内容,第一行的1111和第三行的3333是必打印出来的,第二行的内容具体是什么要看情况。如果在server2上执行则显示主机名,如果在其他机器上执行则显示aaaa

写一个playbook

[jin@rhel801 demo4]$ cat 2.yml 
---
- hosts: db
  tasks:
  - name: 拷贝一个文件过去
    template: src=bb.j2 dest=/opt/bb.conf
[jin@rhel801 demo4]$

这里是把templates/bb.j2拷贝到两台机器的/opt中并命名为bb.conf,运行此 playbook

[jin@rhel801 demo4]$ ansible-playbook 2.yml 

PLAY [db] **********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel803]
ok: [rhel802]

TASK [拷贝一个文件过去] ****************************************************************
changed: [rhel802]
changed: [rhel803]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rhel803                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

查看两台机器上/opt/bb.conf的内容

[jin@rhel801 demo4]$ ansible db -m shell -a "cat /opt/bb.conf"
rhel802 | CHANGED | rc=0 >>
1111
  rhel802
  3333
rhel803 | CHANGED | rc=0 >>
1111
  aaaa
  3333
[jin@rhel801 demo4]$

可以看到,rhel802的/opt/bb.conf的第二行显示的是主机名,rhel803的/opt/bb.conf 的第二行显示的是 aaaa

在if和elif后面是可以写多个判断的,用or或and作为连接符,语法如下

判断1 or 判断11:判断1和判断11只要有一个成立就算成立,只有全部不成立才不算成立

判断1 and 判断11:判断1和判断11只有全部成立才算成立,只要有一个不成立就算不成立

查看下面的jinja2模板文件

[jin@rhel801 templates]$ cat cc.j2 
1111
{% if ansible_fqdn=="rhel802" and ansible_distribution_major_version=="7" %}
 {{ansible_fqdn}}
{% else %}
 aaaa
{% endif %}
 3333
[jin@rhel801 templates]$ 

这里jinja2模板会打印3行内容,第一行和第三行的内容是固定的,为1111和3333。第二行的内容是什么,要看是否满足条件,这里判断被管理主机名为rhel802及系统主版本号为7,二者都要满足,第二行才会显示主机名,否则显示 aaaa。需要注意的是,这里if判断语句太长,特意写成了3行也是没问题的

写一个playbook

[jin@rhel801 demo4]$ cat 3.yml 
---
- hosts: db
  tasks: 
  - name: 我要拷贝一个文件过去
    template: src=cc.j2 dest=/opt/cc.conf
[jin@rhel801 demo4]$

运行此playbook

[jin@rhel801 demo4]$ ansible-playbook 3.yml 

PLAY [db] **********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]
ok: [rhel803]

TASK [我要拷贝一个文件过去] **************************************************************
changed: [rhel802]
changed: [rhel803]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rhel803                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

查看两台机器上/opt/cc.conf的内容

[jin@rhel801 demo4]$ ansible db -m shell -a "cat /opt/cc.conf"
rhel802 | CHANGED | rc=0 >>
1111
  aaaa
  3333
rhel803 | CHANGED | rc=0 >>
1111
  aaaa
  3333
[jin@rhel801 demo4]$

1.2 for循环

一个列表中有多个元素,如果需要依次对列表中的每个元素操作,则可以使用for循环来实现,for 循环的语法如下

1 {% for i in 列表名 %}
2 {{i}}
3 {% endfor %}

这里首先把列表中的第一个元素赋值给i,执行中间的操作;然后把第二个元素赋值给i执行中间的操作,以此类推,直到把最后一个元素赋值给i。看下面的例子

[jin@rhel801 templates]$ cat dd.conf.j2 
{% set list1=['aa','bb','cc'] %}
 1111
{% for i in list1 %}
 {{i}}
{% endfor %}
 5555
[jin@rhel801 templates]$

这里手动在jinja2模板中定义了一个列表(注意定义列表的方式)list1,里面有3个元素,分别为aa、bb、cc。然后对这个列表的内容进行循环

这里jinja2模板生成的文件有5行内容,第1行和第5行的内容是固定的,为1111和5555。 第2~4行是循环列表list1 中的值,为aa、bb、cc

写一个 playbook,内容如下

[jin@rhel801 demo4]$ cat 4.yml 
---
- hosts: rhel802
  tasks:
  - name: 拷贝一个文件到远端主机
    template: src=dd.conf.j2 dest=/opt/dd.conf
[jin@rhel801 demo4]$

运行此playbook,内容如下

[jin@rhel801 demo4]$ ansible-playbook 4.yml 

PLAY [rhel802] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]

TASK [拷贝一个文件到远端主机] *************************************************************
changed: [rhel802]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

查看rhel802 上/opt/dd.conf的内容

[jin@rhel801 demo4]$ ansible rhel802 -m shell -a "cat /opt/dd.conf"
rhel802 | CHANGED | rc=0 >>
 1111
 aa
 bb
 cc
 5555
[jin@rhel801 demo4]$

除了jinja2模板中手动定义的列表,一般情况下,我们会在playbook中定义列表,然后对列表中的元素进行循环

练习:写一个变量文件users_list.txt,里面包含一个名称为users的列表

[jin@rhel801 demo4]$ cat users_list.txt 
users:
- uname: tom
  age: 20
  sex: man

- uname: bob
  age: 21
  sex: man

- uname: mary
  age: 22
  sex: woman

- uname: wangwu
  age: 23
  sex: man

[jin@rhel801 demo4]$

在 templates目录下写一个ee.j2,里面写一个 for 语句循环users列表

[jin@rhel801 templates]$ cat ee.j2 
现在公司中所有员工姓名是:
{% for i in users %}
 {{i.uname}}
{% endfor %}

[jin@rhel801 templates]$

循环每个元素时,只打印元素中的uname变量。写一个名称为5.yaml的playbook,加载变量文件 users list.txt

[jin@rhel801 demo4]$ cat 5.yml 
---
- hosts: rhel802
  vars_files:
  ‐ users_list.txt
  tasks:
  - name: 拷贝一个文件到远端主机
    template: src=ee.j2 dest=/opt/ee.conf
[jin@rhel801 demo4]$

这里通过 template模块把ee.j2拷贝到被管理主机的/opt 中并命名为ee.conf。查看 rhel802上/opt/ee.conf的内容

[jin@rhel801 demo4]$ ansible-playbook 5.yml 

PLAY [rhel802] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]

TASK [拷贝一个文件到远端主机] *************************************************************
changed: [rhel802]

PLAY RECAP *********************************************************************
rhel802                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

查看被管理主机的/opt/ee.conf,里面包括users列表中所有的用户名

[jin@rhel801 demo4]$ ansible rhel802 -m shell -a "cat /opt/ee.conf"
rhel802 | CHANGED | rc=0 >>
现在公司中所有员工姓名是:
 tom
 bob
 mary
 wangwu
[jin@rhel801 demo4]$

3.3 handlers

前面讲了模板的使用,但是后期我们可能需要修改模板的内容,然后重新拷贝到各个机器,此时需要重启httpd服务才会生效,先看下面的例子

先获取 httpd.conf的配置文件,获取的httpd.conf中没有任何空白行和注释行

[jin@rhel801 ~]$ egrep -v '#|^#' /etc/httpd/conf/httpd.conf > httpd.conf.j2

修改此httpd.conf.j2的第三行,把原来Listen后面的端口80换成{{myport}},让 httpd.confj2引用myport变量,内容如下

[jin@rhel801 demo4]$ head -4 httpd.conf.j2 

ServerRoot "/etc/httpd"

Listen {{myport}}
[jin@rhel801 demo4]$

为了不让例子变得太复杂,先关闭 SELinux("/etc/selinux/config")

写一个名称为hand-1.yml的playbook

[jin@rhel801 demo4]$ cat hand-1.yml 
---
- hosts: rhel802
  vars:
    myport: 80
  tasks: 
  - name: task1安装httpd
    yum: name=httpd state=installed
  - name: task2拷贝配置文件
    template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  - name: task3启动httpd服务
    service: name=httpd state=started
[jin@rhel801 demo4]$

第一个task用于安装 htpd,第二个task用于把模板httpd.conf.j2拷贝到被管理机器,第三个 task用于启动httpd服务,第一次是可以正常运行的

下面修改myport的值为80

[jin@rhel801 demo4]$ ansible-playbook hand-1.yml 

PLAY [rhel802] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [rhel802]

TASK [task1安装httpd] ************************************************************
ok: [rhel802]

TASK [task2拷贝配置文件] *************************************************************
changed: [rhel802]

TASK [task3启动httpd服务] **********************************************************
changed: [rhel802]

PLAY RECAP *********************************************************************
rhel802                    : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[jin@rhel801 demo4]$

启动成功 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/269575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【RocketMQ】Console页面报错:rocketmq remote exception,connect to xxx failed.

现象 console报错,无法连接该节点,把该节点杀掉,还是继续报错,重启之后,报错的端口变成11911。 分析 正常一个broker会启动三个端口,不同版本的规律不太一样,4.X版本是: 配置文件…

软件工程经济学习题 答案(不保证对错,找不到答案)

一、资金等值计算 1.某IT企业今年向银行贷款20万元以购置一台设备。若银行贷款利率为10%,规定10年内等额偿还,试求每年的偿还金额。 2.某软件企业向银行贷款200万元,按年利率为8%进行复利计息,试求该企业第5年末连本带利一次偿还银…

计算机视觉技术-使用图像增广进行训练

让我们使用图像增广来训练模型。 这里,我们使用CIFAR-10数据集,而不是我们之前使用的Fashion-MNIST数据集。 这是因为Fashion-MNIST数据集中对象的位置和大小已被规范化,而CIFAR-10数据集中对象的颜色和大小差异更明显。 CIFAR-10数据集中的前…

Cost Calculator Builder PRO v3.1.46 已注册 – WordPress 插件

成本计算器生成器 PRO v3.1.46:WordPress 插件全解析 一、插件概述 "成本计算器生成器 PRO v3.1.46"是一款强大的WordPress插件,专为需要创建报价、价格和项目估算表的用户设计。这款插件集成了众多高级功能,可帮助用户高效地管理…

LVM逻辑卷管理

传统磁盘存在的问题: 1.当分区不够用时,无法扩展大小。 2.当磁盘分区不够用时,只能通过添加硬盘的方式,但是新添加的硬盘只能当作独立的系统文件存在。 所以如果生产环境的数据库的数据目录满了,只能通过添加新的硬…

计算机毕业设计------SSM网上超市购物商城管理系统

项目介绍 本项目分为前后台,分为普通用户、管理员两种角色。前台普通用户登录,后台管理员登录; 管理员角色包含以下功能: 登录页面,用户查看,一级分类管理,二级分类管理,商品管理,查看订单,留言管理等功能。 用户角色包含以下功…

Frequency-domain MLPs are More EffectiveLearners in Time Series Forecasting

本论文来自于 37th Conference on Neural Information Processing Systems (NeurIPS 2023) Abstract 时间序列预测在金融、交通、能源、医疗等不同行业中发挥着关键作用。虽然现有文献设计了许多基于 RNN、GNN 或 Transformer 的复杂架构(注意力机制的计算太占用资…

探索前端构建可视化应用的思路

一、前言 前端社区里,低代码/无代码是被讨论的火热赛道。简单来说低代码就是通过编写少量代码的方式完成应用的开发及上线,而无代码是低代码的子集,不需要编写代码通过配置的方式即可完成整个应用的开发。目前集团内部的低代码平台已经有很多…

【JMeter入门】—— JMeter介绍

1、什么是JMeter Apache JMeter是Apache组织开发的基于Java的压力测试工具,用于对软件做压力测试。它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 (Apache JMeter是100%纯JAVA桌面应用程序) Apache JMeter可以用于对静…

ElasticSearch入门介绍和实战

目录 1.ElasticSearch简介 1.1 ElasticSearch(简称ES) 1.2 ElasticSearch与Lucene的关系 1.3 哪些公司在使用Elasticsearch 1.4 ES vs Solr比较 1.4.1 ES vs Solr 检索速度 2. Lucene全文检索框架 2.1 什么是全文检索 2.2 分词原理之倒排索引…

OpenCV之图像匹配与定位

利用图像特征的keypoints和descriptor来实现图像的匹配与定位。图像匹配算法主要有暴力匹配和FLANN匹配,而图像定位是通过图像匹配结果来反向查询它们在目标图片中的具体坐标位置。 以QQ登录界面为例,将整个QQ登录界面保存为QQ.png文件,QQ登…

App测试时常用的adb命令你都掌握了哪些呢?

adb 全称为 Android Debug Bridge(Android 调试桥),是 Android SDK 中提供的用于管理 Android 模拟器或真机的工具。 adb 是一种功能强大的命令行工具,可让 PC 端与 Android 设备进行通信。adb 命令可执行各种设备操作&#xff0…

天软特色因子看板 (2023.12 第14期)

该因子看板跟踪天软特色因子A06008聪明钱因子(beta)),该因子为以分钟行情价量信息为基础,识别聪明钱交易,用以刻画机构交易行为 值越大,越反映其悲观情绪,反之,反映其乐观情绪。 今日为该因子跟踪第14期&am…

ACM模式Java输入输出模板

输入输出练习网站:https://kamacoder.com/ Java读写模板 Scanner 方式一:Scanner(效率不高) public class Main {public static void main(String[] args) {// 第一个方式ScannerScanner sc new Scanner(System.in);String s …

Python画皮卡丘

代码: import turtledef getPosition(x, y):turtle.setx(x)turtle.sety(y)print(x, y)class Pikachu:def __init__(self):self.t turtle.Turtle()t self.tt.pensize(3)t.speed(9)t.ondrag(getPosition)def noTrace_goto(self, x, y):self.t.penup()self.t.goto(…

WebGL开发建筑和设计教育应用

使用 WebGL 开发建筑和设计教育应用可以为学生提供沉浸式的三维体验,使他们能够在虚拟环境中探索建筑结构、材料和设计理念。以下是开发建筑和设计教育应用的一般步骤,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司&…

【开源】基于JAVA的学校热点新闻推送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…

数据结构与算法基础

数组 稀疏矩阵 题目 代入法选A 数据结构的定义 线性表 顺序存储和链式存储的对比 队列与栈 题目 答案选:D 广义表 树与二叉树 二叉树遍历 图中前序遍历结果是? 1,2,4,5,7,8,3,6 图中中序遍历结果是? 4,7,8,5,2,1,3,6 图中后序遍历结果是…

利用 OpenAI API 进行文本聚类和标记

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。 欢迎关注公众号 原文标题:Text Clustering and Labeling Utilizing OpenAI API 原文地址:https://medium.com/kbd…

Vue 项目中部分页面保存后不能自动编译

原因: 可能引有组件时,引用的组件大小写名称不一致,包括文件名和目录,检查一下。 如果是这样引用,目录名Modal的M变大写了,虽然整体是能编辑过去,但是保存后不能自动编译了。