当前位置: 首页 > news >正文

金融网站 改版方案迪庆企业网站建设公司

金融网站 改版方案,迪庆企业网站建设公司,网站建设与管理教学计划,公司网站上传不了图片Elasticsearch 是一款基于 Lucene 库构建的开源、分布式、RESTful 风格的搜索引擎和分析引擎#xff0c;具有强大的全文搜索、数据分析、机器学习等功能#xff0c;广泛应用于日志分析、实时数据分析、全文检索等场景。 核心概念 索引#xff08;Index#xff09;#xf…Elasticsearch 是一款基于 Lucene 库构建的开源、分布式、RESTful 风格的搜索引擎和分析引擎具有强大的全文搜索、数据分析、机器学习等功能广泛应用于日志分析、实时数据分析、全文检索等场景。 核心概念 索引Index类似于传统数据库中的数据库是存储数据的逻辑容器。一个索引可以包含多个类型的数据每个索引都有一个唯一的名称用于标识。类型Type在早期版本中一个索引可以有多个类型用来区分不同类型的数据但在 7.x 及以上版本中一个索引只能有一个类型且默认类型为“_doc”。文档Document是 Elasticsearch 中存储和检索的基本数据单元以 JSON 格式表示。每个文档都有一个唯一的 ID用于在索引中定位和操作文档。字段Field是文档中的一个属性或键值对用于存储具体的数据内容如姓名、年龄、价格等。字段有不同的数据类型如文本、数字、日期等不同的数据类型决定了字段的存储和检索方式。 主要特点 高性能全文搜索基于 Lucene 的倒排索引技术能够快速地对文本数据进行全文搜索。它会将文本数据拆分成单词或词汇建立索引当进行搜索时通过查找索引快速定位到包含搜索关键词的文档大大提高了搜索效率。分布式架构可以部署在多个节点上形成一个分布式集群。数据会被自动分片存储在不同的节点上当一个节点出现问题时其他节点可以继续提供服务保证了系统的高可用性和数据的可靠性。同时分布式架构也使得 Elasticsearch 能够处理海量的数据和高并发的请求。易于扩展随着数据量和访问量的增加可以通过简单地增加节点来水平扩展集群。新加入的节点会自动参与数据的存储和查询工作无需对现有系统进行复杂的改造能够灵活地应对业务的增长。RESTful API提供了基于 HTTP 协议的 RESTful 风格的 API 接口方便开发者使用各种编程语言进行集成和开发。通过简单的 HTTP 请求就可以完成数据的增删改查、索引管理、查询分析等各种操作降低了开发难度和成本。多租户支持在 Elasticsearch 集群中可以创建多个索引每个索引可以视为一个独立的“租户”不同租户之间的数据相互隔离。这使得 Elasticsearch 能够在一个集群中同时为多个应用程序或用户提供服务提高了资源利用率。强大的聚合分析功能除了基本的搜索功能还提供了丰富的聚合分析功能如统计、分组、排序、时间序列分析等。可以对搜索结果进行进一步的数据挖掘和分析帮助用户快速获取数据的统计信息和趋势为决策提供支持。 常见应用场景 日志分析能够高效地收集、存储和分析各种日志数据如服务器日志、应用程序日志、网络设备日志等。通过对日志数据的搜索、过滤、聚合分析可以快速定位系统故障、性能瓶颈、安全问题等为运维人员提供有力的工具。实时数据分析适用于需要实时处理和分析大量数据的场景如金融交易监控、社交媒体数据监测、物联网设备数据处理等。Elasticsearch 可以实时地接收数据快速地进行查询和分析及时发现异常情况并做出响应。全文检索为各种需要全文检索功能的应用程序提供支持如电子商务网站的商品搜索、知识管理系统的内容检索、新闻网站的新闻搜索等。能够根据用户的输入关键词快速地在海量文本数据中找到匹配的结果并按照相关性进行排序提升用户体验。机器学习结合 Elasticsearch 的机器学习功能可以对数据进行自动分析和建模实现异常检测、预测分析等高级功能。例如在网络安全领域通过机器学习算法对网络流量数据进行分析自动识别潜在的攻击行为在电商领域预测用户的购买行为和需求。 架构组件 节点Node是 Elasticsearch 集群中的一个服务器实例承担着数据存储、查询处理、集群管理等任务。节点之间通过网络进行通信和协作共同构成一个完整的 Elasticsearch 集群。集群Cluster由一个或多个节点组成通过配置集群名称来标识。集群负责管理节点、分配分片、处理请求等保证数据的一致性和高可用性。集群中的主节点Master Node负责集群级别的操作如创建索引、分配分片、节点发现等数据节点Data Node主要负责存储数据和执行查询操作。分片Shard为了提高数据的存储能力和查询性能索引会被分割成多个分片每个分片是一个独立的 Lucene 索引。分片可以分布在不同的节点上当进行查询时查询请求会被分发到各个分片上并行执行然后将结果汇总返回。分片的数量在索引创建时确定可以根据数据量和查询需求进行合理配置。副本Replica是分片的副本用于提高数据的可靠性和查询性能。当一个分片出现故障时副本可以接管其查询请求保证服务的可用性。同时副本也可以分担查询负载提高查询的并发处理能力。副本的数量可以根据集群的节点数量和可靠性要求进行配置。 数据写入与查询流程 数据写入流程 客户端发送写入请求用户或应用程序通过 Elasticsearch 的 RESTful API 向集群发送数据写入请求请求中包含要写入的索引名称、文档数据等信息。主节点路由请求主节点接收到请求后根据索引的分片策略将写入请求路由到对应的主分片所在的节点。主分片写入数据主分片节点接收到请求后将数据写入本地的分片中并记录操作日志。写入成功后会将操作日志发送给对应的副本分片节点。副本分片同步数据副本分片节点接收到操作日志后会根据日志内容将数据同步到本地的副本分片中。当所有副本分片都成功同步数据后主分片节点会向客户端返回写入成功的响应。数据查询流程 客户端发送查询请求用户或应用程序通过 RESTful API 向集群发送查询请求请求中包含查询条件、索引名称等信息。主节点分发查询请求主节点接收到查询请求后根据索引的分片分布情况将查询请求分发到所有相关的分片所在的节点。分片节点执行查询各个分片节点接收到查询请求后在本地的分片中执行查询操作根据查询条件检索匹配的文档并将查询结果返回给主节点。主节点汇总结果主节点接收到各个分片节点返回的查询结果后对结果进行汇总和排序等处理然后将最终的查询结果返回给客户端。 Elasticsearch基础概念 Index索引(index)就是文档的集合类似数据库的表(table) Document文档Document就是一条条的数据类似数据库中的行Row文档都是JSON格式 Field字段Field就是JSON文档中的字段类似数据库中的列Column MappingMapping映射是索引中文档的约束例如字段类型约束。类似数据库的表结构Schema DSLDSL是elasticsearch提供的JSON风格的请求语句用来操作elasticsearch实现CRUD 倒排索引 正向索引 文档 ID用于唯一标识每个文档类似数据库表中的主键有了它就能精准定位到特定的某一文档。索引项跟在文档 ID 后面包含了文档中的各类关键元素比如文本里的词汇、数据记录的属性值等有的还会附上这些元素在文档中的具体位置信息。 倒排索引 文档Document用来搜索的数据其中的每一条数据就是一个文档。例如一个网页、一个商品信息。 词条Term对文档数据或用户搜索数据利用某种算法分词得到的具备含义的词语就是词条。例如我是中国人就可以分为我、是、中国人、中国、国人这样的几个词条。 对比 正向索引的表结构 id索引 title price 1 小米手机 3499 2 华为手机 4999 3 华为小米充电器 49 4 小米手环 49 搜索流程 1如检查到搜索条件为like %手机%需要找到title中包含手机的数据 2逐条遍历每行数据每个叶子节点比如第1次拿到id为1的数据 3判断数据中的title字段值是否符合条件 4如果符合则放入结果集不符合则丢弃 5回到步骤1 倒排索引的表结构 词条索引 文档id 小米 134 手机 12 华为 23 充电器 3 手环 4 搜索流程 1如用户输入条件华为手机进行搜索。 2对用户输入条件分词得到词条华为、手机。 3拿着词条在倒排索引中查找由于词条有索引查询效率很高即可得到包含词条的文档id1、2、3。 4拿着文档id到正向索引中查找具体文档即可由于id也有索引查询效率也很高。 正向索引 优点 可以给多个字段创建索引 根据索引字段搜索、排序速度非常快 缺点 根据非索引字段或者索引字段中的部分词条查找时只能全表扫描。 倒排索引 优点 根据词条搜索、模糊搜索时速度非常快 缺点 只能给词条创建索引而不是字段 无法根据字段做排序 安装Elasticsearch 1.使用docker安装单机版的Elasticsearch docker run -d \--name es \-e ES_JAVA_OPTS-Xms512m -Xmx512m \-e discovery.typesingle-node \-v es-data:/usr/share/elasticsearch/data \-v es-plugins:/usr/share/elasticsearch/plugins \--privileged \--network es-net \-p 9200:9200 \-p 9300:9300 \--restartalways \elasticsearch:7.12.1 代码解读 -d让容器在后台运行 --name指定创建的容器名称 -e设置容器内的环境变量 -v将容器内的目录挂载到外部的卷上 --privileged以特权模式运行容器 --network将容器连接到名为 es-net 的 Docker 网络在我们搭建服务器的时候可以创建一个docker网络将要互相通信的放在这一个网络里面。注意这里需要先用docker network create创建一个docker网络这里才能指定 -p将容器的端口映射到主机的端口 --restartalways设置容器自启动 elasticsearch:7.12.1要运行的 Docker 镜像名称和标签如果我们指定这个镜像本地没有这个版本就会进行下载。注意这里我们采用的是elasticsearch的7.12.1版本由于8以上版本的JavaAPI变化很大在企业中应用并不广泛企业中应用较多的还是8以下的版本。 2.防火墙开放端口 #1.开放es端口 firewall-cmd --zonepublic --add-port9200/tcp --add-port9300/tcp --permanent #2.重新加载防火墙配置 firewall-cmd --reload 也可以关闭防火墙 systemctl stop firewalld 3.访问9200端口验证es是否启动成功 地址格式主机IP:9200 IK分词器 Elasticsearch的关键就是倒排索引而倒排索引依赖于对文档内容的分词而分词则需要高效、精准的分词算法IK分词器就是这样一个中文分词算法。 安装 方法一在线安装 docker exec -it es ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip 重启es容器 docker restart es 方法二离线安装 首先查看之前安装的es容器的plugins数据卷目录 docker volume inspect es-plugins 结果如下  进入/var/lib/docker/volumes/es-plugins/_data目录将我们本地的ik上传到这个目录下 重启es容器 docker restart es 使用 IK分词器包含两种模式 ik_smart智能语义切分 示例 POST /_analyze {analyzer: ik_smart,text: 我是一个程序员 }结果 {tokens : [{token : 我,start_offset : 0,end_offset : 1,type : CN_CHAR,position : 0},{token : 是,start_offset : 1,end_offset : 2,type : CN_CHAR,position : 1},{token : 一个,start_offset : 2,end_offset : 4,type : CN_WORD,position : 2},{token : 程序员,start_offset : 4,end_offset : 7,type : CN_WORD,position : 3}] }ik_max_word最细粒度切分 示例 POST /_analyze {analyzer: ik_max_word,text: 我是一个程序员 }结果  {tokens : [{token : 我,start_offset : 0,end_offset : 1,type : CN_CHAR,position : 0},{token : 是,start_offset : 1,end_offset : 2,type : CN_CHAR,position : 1},{token : 一个,start_offset : 2,end_offset : 4,type : CN_WORD,position : 2},{token : 一,start_offset : 2,end_offset : 3,type : TYPE_CNUM,position : 3},{token : 个,start_offset : 3,end_offset : 4,type : COUNT,position : 4},{token : 程序员,start_offset : 4,end_offset : 7,type : CN_WORD,position : 5},{token : 程序,start_offset : 4,end_offset : 6,type : CN_WORD,position : 6},{token : 员,start_offset : 6,end_offset : 7,type : CN_CHAR,position : 7}] }拓展词典 随着互联网的发展“造词运动”也越发的频繁。出现了很多新的词语在原有的词汇列表中并不存在如“逆天、依托答辩、我了个豆” POST /_analyze {analyzer: ik_max_word,text: 逆天、依托答辩、我了个豆 } 结果 {tokens : [{token : 逆,start_offset : 0,end_offset : 1,type : CN_CHAR,position : 0},{token : 天,start_offset : 1,end_offset : 2,type : CN_CHAR,position : 1},{token : 依托,start_offset : 3,end_offset : 5,type : CN_WORD,position : 2},{token : 答辩,start_offset : 5,end_offset : 7,type : CN_WORD,position : 3},{token : 我,start_offset : 8,end_offset : 9,type : CN_CHAR,position : 4},{token : 了,start_offset : 9,end_offset : 10,type : CN_CHAR,position : 5},{token : 个,start_offset : 10,end_offset : 11,type : CN_CHAR,position : 6},{token : 豆,start_offset : 11,end_offset : 12,type : CN_CHAR,position : 7}] }可以看到逆天和我了个豆都无法正确分词。 所以要想正确分词IK分词器的词库也需要不断的更新IK分词器提供了扩展词汇的功能。 1打开IK分词器config目录 注意如果采用在线安装的通过默认是没有config目录的可以去网上找一些词库让后创建一个config文件目录放在config目录下 2在IKAnalyzer.cfg.xml配置文件内容添加 ?xml version1.0 encodingUTF-8? !DOCTYPE properties SYSTEM http://java.sun.com/dtd/properties.dtd propertiescommentIK Analyzer 扩展配置/comment!--可以在这里配置自己的扩展字典 --entry keyext_dictext.dic/entry /properties3新建ext.dic文件用记事本或者其他编辑器打开ext.dic文件然后添加自己想要的词语即可 4重启elasticsearch docker restart es# 查看 日志 docker logs -f elasticsearch 5.重启之后再次执行之前的命令可以正确分词了 {tokens : [{token : 逆天,start_offset : 0,end_offset : 2,type : CN_WORD,position : 0},{token : 依托答辩,start_offset : 3,end_offset : 7,type : CN_WORD,position : 1},{token : 依托,start_offset : 3,end_offset : 5,type : CN_WORD,position : 2},{token : 答辩,start_offset : 5,end_offset : 7,type : CN_WORD,position : 3},{token : 我了个豆,start_offset : 8,end_offset : 12,type : CN_WORD,position : 4}] }还可以在IKAnalyzer.cfg.xml加上如下配置实现更多功能 ?xml version1.0 encodingUTF-8? !DOCTYPE properties SYSTEM http://java.sun.com/dtd/properties.dtd propertiescommentIK Analyzer 扩展配置/comment!--用户可以在这里配置自己的扩展字典 --entry keyext_dictext.dic/entry!--用户可以在这里配置自己的扩展停止词字典--entry keyext_stopwordsstopword.dic/entry!--用户可以在这里配置远程扩展字典 --!-- entry keyremote_ext_dictwords_location/entry --!--用户可以在这里配置远程扩展停止词字典--!-- entry keyremote_ext_stopwordswords_location/entry -- /propertiesRESTAPI使用 ES官方提供了各种不同语言的客户端用来操作ES。这些客户端的本质就是组装DSL语句通过http请求发送给ES。 官方文档地址 Elasticsearch Clients | Elastic 由于ES目前最新版本是8.8提供了全新版本的客户端老版本的客户端已经被标记为过时。而我们采用的是7.12版本因此只能使用老版本客户端 然后选择7.12版本HighLevelRestClient版本 1.引入es的RestHighLevelClient依赖 dependencygroupIdorg.elasticsearch.client/groupIdartifactIdelasticsearch-rest-high-level-client/artifactIdversion7.12.1/version /dependency 2.初始化RestHighLevelClient public class IndexTest {private RestHighLevelClient client;BeforeEachvoid setUp() {this.client new RestHighLevelClient(RestClient.builder(HttpHost.create(http://192.168.181.32:9200)//es服务ip地址:端口号));}Testvoid testConnect() {System.out.println(client);//执行不好错就行了}AfterEachvoid tearDown() throws IOException {this.client.close();} } 3.索引库相关操作 public class ElasticIndexTest {private static final String MAPPING_TEMPLATE {mappings: {properties: {id: {type: keyword},name: {type: text,analyzer: ik_smart},price: {type: integer},image: {type: keyword,index: false},category: {type: keyword},brand: {type: keyword},sold: {type: integer},commentCount: {type: integer,index: false},isAD: {type: boolean},updateTime: {type: date}}}};//JDK15新特性三引号private RestHighLevelClient client;//创建Testvoid testCreateIndex() throws IOException {//准备request对象CreateIndexRequest request new CreateIndexRequest(items);//准备请求参数request.source(MAPPING_TEMPLATE, XContentType.JSON);//发送请求client.indices().create(request, RequestOptions.DEFAULT);}//判断是否存在Testvoid testExistsndex() throws IOException {//准备request对象GetIndexRequest request new GetIndexRequest(items);//发送请求boolean exists client.indices().exists(request, RequestOptions.DEFAULT);System.out.println(exists exists);}//删除Testvoid testDeleteIndex() throws IOException {//准备request对象DeleteIndexRequest request new DeleteIndexRequest(items);//发送请求client.indices().delete(request, RequestOptions.DEFAULT);}BeforeEachvoid setUp() {client new RestHighLevelClient(RestClient.builder(HttpHost.create(http://192.168.181.32:9200)));}AfterEachvoid tearDown() throws IOException {if (client ! null) {client.close();}} }4.文档相关操作 package com.hmall.item.es;import cn.hutool.core.bean.BeanUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.hmall.item.domain.po.Item; import com.hmall.item.domain.po.ItemDoc; import com.hmall.item.service.IItemService; import org.apache.http.HttpHost; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException; import java.util.List;SpringBootTest(properties spring.profiles.activelocal) public class ElasticDocumentTest {private RestHighLevelClient client;Autowiredprivate IItemService itemService;BeforeEachvoid setUp() {client new RestHighLevelClient(RestClient.builder(HttpHost.create(http://192.168.181.32:9200)));}//创建文档Testvoid createDoc() throws IOException {//准备文档数据//1.查询数据Item item itemService.getById(577967L);//2.把数据库数据转成文档数据ItemDoc itemDoc BeanUtil.copyProperties(item, ItemDoc.class);//准备request对象IndexRequest request new IndexRequest(items).id(itemDoc.getId());//构建请求参数request.source(JSONUtil.toJsonStr(itemDoc), XContentType.JSON);//发送请求client.index(request, RequestOptions.DEFAULT);}//获取文档数据Testvoid testGetDoc() throws IOException {//准备request对象GetRequest request new GetRequest(items, 577967);//发送请求GetResponse response client.get(request, RequestOptions.DEFAULT);//获取响应结果中的sourceString json response.getSourceAsString();//转成java对象ItemDoc itemDoc JSONUtil.toBean(json, ItemDoc.class);System.out.println(itemDoc itemDoc);}//删除文档Testvoid testDelDoc() throws IOException {//准备request对象DeleteRequest request new DeleteRequest(items, 577967);//发送请求client.delete(request, RequestOptions.DEFAULT);}//修改文档数据Testvoid testUpdateDoc() throws IOException {//准备request对象UpdateRequest request new UpdateRequest(items, 577967);request.doc(price, 29900);//发送请求client.update(request, RequestOptions.DEFAULT);}//批量操作文档新增Testvoid testBulkDoc() throws IOException {int pageNo 1, pageSize 500;while (true) {PageItem page itemService.lambdaQuery().eq(Item::getStatus, 1).page(Page.of(pageNo, pageSize));ListItem records page.getRecords();if (records null || records.isEmpty()) {return;}//准备BulkRequest对象BulkRequest request new BulkRequest();for (Item item : records) {//添加批量提交的请求request.add(new IndexRequest(items).id(item.getId().toString()).source(JSONUtil.toJsonStr(BeanUtil.copyProperties(item, ItemDoc.class)), XContentType.JSON));}//提交请求client.bulk(request, RequestOptions.DEFAULT);pageNo;}}AfterEachvoid tearDown() throws IOException {if (client ! null) {client.close();}} } 5.查询数据相关操作 public class ElasticSearchTest {private RestHighLevelClient client;private static void parseResponseResult(SearchResponse response) {//得到命中的数据SearchHits hits response.getHits();long total hits.getTotalHits().value;System.out.println(total total);for (SearchHit hit : hits) {//解析数据String json hit.getSourceAsString();//封装itemDocItemDoc doc JSONUtil.toBean(json, ItemDoc.class);//处理高亮字段MapString, HighlightField hfs hit.getHighlightFields();if (hfs ! null !hfs.isEmpty()) {//更具高亮字段名获取高亮结果HighlightField hf hfs.get(name);//用获取到的高亮值覆盖原来非高亮的字段值String hfName hf.getFragments()[0].toString();doc.setName(hfName);}System.out.println(doc doc);}}//查询全部Testvoid testMatchAll() throws IOException {//创建SearchRequest request new SearchRequest(items);//组织DSL查询参数request.source().query(QueryBuilders.matchAllQuery());//发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);//解析结果parseResponseResult(response);}//根据条件查询复合查询Testvoid testSearch() throws IOException {//创建SearchRequest request new SearchRequest(items);//组织DSL查询参数request.source().query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery(name, 脱脂牛奶)).filter(QueryBuilders.termQuery(brand, 德亚)).filter(QueryBuilders.rangeQuery(price).lt(30000)));//发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);//解析结果parseResponseResult(response);}//分页排序Testvoid testPageAndSort() throws IOException {int pageNo 1, pageSize 5;// 1.创建RequestSearchRequest request new SearchRequest(items);// 2.组织请求参数// 2.1.搜索条件参数request.source().query(QueryBuilders.matchQuery(name, 脱脂牛奶));// 2.2.排序参数request.source().sort(price, SortOrder.ASC);// 2.3.分页参数request.source().from((pageNo - 1) * pageSize).size(pageSize);// 3.发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);// 4.解析响应parseResponseResult(response);}//根据条件获取高亮数据Testvoid testHighlight() throws IOException {//创建SearchRequest request new SearchRequest(items);//组织DSL查询参数//query条件request.source().query(QueryBuilders.matchQuery(name, 脱脂牛奶));//高亮条件request.source().highlighter(SearchSourceBuilder.highlight().field(name));//发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);//解析结果parseResponseResult(response);}//数据聚合Testvoid testAgg() throws IOException {//创建SearchRequest request new SearchRequest(items);//组织DSL查询参数//query条件request.source().size(0);//聚合条件String brandAggName brandAgg;request.source().aggregation(AggregationBuilders.terms(brandAggName).field(brand).size(10));//发送请求SearchResponse response client.search(request, RequestOptions.DEFAULT);//解析结果Aggregations aggregations response.getAggregations();//根据聚合名称获取聚合Terms aggTerms aggregations.get(brandAggName);//获取bucketsList? extends Terms.Bucket buckets aggTerms.getBuckets();//遍历每一个bucketfor (Terms.Bucket bucket : buckets) {System.out.println(brand:bucket.getKeyAsString());System.out.println(count:bucket.getDocCount());}}BeforeEachvoid setUp() {client new RestHighLevelClient(RestClient.builder(HttpHost.create(http://192.168.181.32:9200)));}AfterEachvoid tearDown() throws IOException {if (client ! null) {client.close();}} }
http://www.hkea.cn/news/14591079/

相关文章:

  • 广告设计就业方向和前景搜索优化推广公司
  • 智慧景区网站服务建设做网站编辑需要学什么
  • 云南 旅游 网站建设开源php网站开发
  • 怎么做网站跟域名h5制作方法
  • 自己做衣服的网站手机房屋平面设计软件
  • 深圳高端电商网站建设者html5的网站
  • 鞋业有限公司网站设计wordpress自定义类型使用模板
  • 深圳微信网站unity网络游戏开发
  • 做网站用什么后缀格式做好企业网站的建设要注意什么
  • 武威建设厅网站制作网站的免费软件
  • 瑞幸咖啡网站建设方案做网站手机端需要pc端的源代码吗
  • 在线编程的网站sql数据库添加网站
  • 可以做游戏的网站有哪些方面wordpress主题不分页
  • 佛山网站优化什么价格网站制作实训
  • 蚂蚁中国网站建设wordpress 父级页面
  • lamp网站开发经验求制作网站
  • 邢台有什么网站wordpress页面突然不能访问
  • 做的好的农产品网站十堰网络销售
  • 公司网站维护工作龙口网站建设公司
  • 足球比分网站建设网站建设运维情况
  • 网站建设公司合同个人养老保险账户余额查询
  • 论坛类网站设计电商是干什么的是什么意思
  • 家居装修企业网站源码龙华网站建设方案表
  • 东莞网站推广模板信用网站标准化建设模块都有哪些
  • 利用模板如何制作网站设计图片素材
  • 网站建设注册哪类商标平面设计技术培训机构
  • 甘肃网站建设域名注册公司wordpress 伪静态设置
  • wordpress网站熊掌粉丝关注网站中英文版怎么做
  • 建站宝盒全能版怎么在微信上做网站
  • 南京中小企业网站制作平面设计培训机构排行