1.蜘蛛爬取的数据,如何处理
(1)关系型数据库,SQL工具,入门容易,深入难。DBA(Oracle-存储过程-视图-大型项目组禁用)
ASP+com+ 存储过程难以维护,
视图View
SELECT * FROM item_view WHERE id=536563 先查询所有数据,然后过滤数据
SELECT * FROM tb_item WHERE id=536563 直接过滤数据(SQL优化)
强调关系:部门和人员(一对多);商品和商品描述(一对一)
(2)非关系型数据库,
html,xml,word,excel 半关系
image,avi 完成非关系型
no-sql not only sql
redis内存数据库kv
hbase 表的数据量轻松过亿(列存储),oracle单表支持亿,千万;mysql单表支持千万,百万
mongodb 可以存文件,word文档、excel文档、视频,而传统的关系型数据库中如果存储这些大文件,会使索引失效
传统数据库查询
select * from tb_item where title like ‘%魅族全网通%’
select * from tb_item where tilte like ‘%魅族%’ and ‘全网通’(全表遍历)
问题:
1) 怎么拆开?
2) 海量数据如何瞬间就查出来呢?
蜘蛛扒取非结构化数据,
1) 数据海量,数量太大了,检索速度太慢
2) 分词
3) 创建索引,全文索引
例子:
doc1:中华人民共和国
doc2:中华人民万岁
1) 分词,创建索引
term不能再拆分,中华:中华,中,华
(中华,1),(人民,1),(共和国,1)
(中华,2),(人民,2),(万岁,2)
索引表:
中华(1,2)
人民(1,2)
共和国(1)
万岁(2)
2) 检索
搜索“中华”,到这个索引表,找到term,返回文章1和文章2
构建自己的搜索引擎
上面这种方式就叫“全文检索”,方式叫倒排索引!
全文检索步骤:
1) 把文章分词(创建索引)
2) 检索
3) 把检索条件分词
难点:
1) 分词依据(分词词库-字典)
2) 创建索引 luceneapache(API) final static
3) 创建集群服务 solrapache(服务war包,集群(负载均衡,单点故障))
solr等价elesticsearch
solr业务系统
elesticsearch轻松构建几十数据量的检索,1s查出(大数据数据检索)(知乎)
solr在创建索引过程比es弱。
es在构建海量数据索引过程非常快,几乎和日常数据量速度一样
solr如果数据量小构建索引还是非常快,但是如果数据量大,索引构建速度就慢了。
2.luence
(1)maven依赖
<!-- lucene -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>4.10.2</version>
</dependency>
<!-- IK分词器,maven官网没有,自己按下面坐标建立路径 -->
<dependency>
<groupId>org.wltea.analyzer</groupId>
<artifactId>ik-analyzer</artifactId>
<version>2012FF_u1</version>
</dependency>
(2)编码-穿件索引
例子:以一个商品为例
package com.jt.luence;
import java.io.File;
import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.DoubleField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class TestLuence {
@Test//建立索引
public void test01() throws IOException{
//1.创建一个document对象 org.apache.lucene.document.Document
Document doc = new Document();
//如果按id来查询,需要将id加入doc的一个属性(org.apache.lucene.document.LongField;)
//store表识创建索引时是否保存,索引实际上就是一个文件
doc.add(new LongField("id", 2402694L, Store.YES));
/**
* StringField和TextField有什么区别?
StringField不分词,把整个内容作为一个分词。一般也不是用来查询。Store.YES.
TextField会分词,按各个term来查询
*/
doc.add(new org.apache.lucene.document.TextField("title",
"小米5 全网通 高配版 3GB内存 64GB ROM 白色 移动联通电信4G手机", Store.YES));
doc.add(new org.apache.lucene.document.TextField("sellPoint",
"该商品已下柜,欢迎挑选其他商品!", Store.YES));
doc.add(new DoubleField("price", 1799.00, Store.YES));
doc.add(new TextField("itemDesc","//c-nfa.jd.com/adclick?keyStr=6PQwtwh0f06syGHwQVvRO2qQjwLJ5GHB8CWaVmO7akxE4PBdL2U9aYjtXf0gd37ks791zJuQs2q4I2lpGNOzQQn9fekfXSNiJzgQO88Gv48J7YZU9PHhVH9aIOun3VaO9VEKOHcOEXc2lnu6+dkNEO1SqyDIWE/kI3XzWSi64L5JZPhJaWrgFoMsVyo2W/6sAkuOIdHLRtkW/q4CIdzM/gKe2acHG0Ajuj9L8JXxidE+hmSpgLz9xmR1xEiObDPEY2cXhMASnNvmSUyLnxgFsxMv49nQdfWafuMVCtVmz8qXOlcppL6VE6XAjxQTKJJ8WOo1bdnPYgppNB+nDWfC8A==&cv=2.0&url=//sale.jd.com/act/46aIRiwSg1J.html",Store.YES));
doc.add(new StringField("image","http://img14.360buyimg.com/n1/s450x450_jfs/t2494/324/1615617468/268135/1677b798/56cd80c5N06181c58.jpg",Store.YES));
//2.创建索引,索引文件
Directory dir = FSDirectory.open(new File("./index")); //在当前工程运行目录中创建一个index目录
//Analyzer analyzer = new StandardAnalyzer(); //标准分词器
Analyzer analyzer = new IKAnalyzer(); //中文分词器
//luence和solr的版本不能轻易升级,4.10.2和5.2.1的API不一样,所以此处导入的版本要和你导入jar包的版本一致
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
IndexWriter indexWriter = new IndexWriter(dir, config );
indexWriter.addDocument(doc); //对上面的文章就创建索引文件
indexWriter.close();
dir.close();
}
}
执行后再项目文件夹中产生文件夹
文件夹中有产生的索引文件
都是二进制文件,文本编译器无法查看,使用索引查看器查看
分析结果
(3)编码-检索
@Test //检索
public void search() throws IOException{
Directory dir = FSDirectory.open(new File("./index"));
//打开索引目录,创建一个检索对象
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(dir));
//创建Term查询方式,查询title字段,查询内容“小米”
Query query = new TermQuery(new Term("title","小米"));
TopDocs topDosc = searcher.search(query , 10); //返回最前面的10条记录
//遍历TopDocs,ScoreDoc得分:百度竞价排名,利用外部值,对得分进行改变,从而导致排名先后位置发生变化。
//最好按照命中率,查询时这个文章按这个查询条件用户的点击率最高。
for(ScoreDoc scoreDoc : topDosc.scoreDocs){//从searcher对象中找到当前的这个docDocument doc = searcher.doc(scoreDoc.doc);String title = doc.get("title");System.out.println(title);}}(4)ik分词器
资源:点击打开链接
由于maven没有,所以可以自己放入仓库中,然后写坐标导入工程,坐标在(1)maven依赖中有
换了分词器后最好将文夹中原先的分词文件清空后重新生成
检索时,只有分词器中分的词有你查询的关键字才能查出对应的内容
(5)索引查看器的使用
可以测试