数据查重脚本基于JavaScript编写,内置了12种查重归并规则,并支持自定义查重规则的扩展和编写。
### 数据查重规则脚本使用说明
数据查重脚本基于JavaScript编写,内置了12种查重归并规则,并支持自定义查重规则的扩展和编写。
JavaScript 语法暂只支持到 ECMAScript 5.1
### 内置查重规则
- 若ISBN/ISSN/统一书刊号只要有一个相同,满足以下条件之一可判为重复记录。
| 规则名称 | 规则编号 | 使用方式 |
|------------------|------|------------------|
| 题名和出版年相同 | 11 | merge.handle(11) |
| 若无出版年,题名和页码相同 | 12 | merge.handle(12) |
| 若无出版年、页码,题名和版本相同 | 13 | merge.handle(13) |
- 若无ISBN/ISSN/统一书刊号,满足以下条件之一可判为重复记录。
| 规则名称 | 规则编号 | 使用方式 |
|--------------------------|------|-----------------|
| 题名、出版者、出版年和页码相同 | 1 | merge.handle(1) |
| 若无页码,题名、出版者、出版年、责任者相同 | 2 | merge.handle(2) |
| 若无出版年,题名、出版者、页码和责任者相同 | 3 | merge.handle(3) |
| 若无出版年、责任者,题名、出版者、页码和版本相同 | 4 | merge.handle(4) |
| 若无出版年、页码,题名、出版者、责任者和版本相同 | 5 | merge.handle(5) |
| 若无出版者,题名、出版年、页码和责任者相同 | 6 | merge.handle(6) |
| 若无出版者、责任者,题名、出版年、页码和版本相同 | 7 | merge.handle(7) |
| 若无出版者、页码,题名、出版年、责任者和版本相同 | 8 | merge.handle(8) |
| 若无出版者、出版年,题名、页码、责任者和版本相同 | 9 | merge.handle(9) |
#### 使用说明
- 使用内置内置查重规则: 使用 merge.handle(规则编号) 调用对应的查重逻辑,handle方法支持支出输入多种规则编号
如:merge.handle(规则编号1...规则编号N) 。
- #### 内置规则使用示例
` 注意:一个归并只能有一个 merge.handle(规则编号) 方法`
###### **方式1**
```javascript
// 使用规则编号1进行查重
(merge.handle(1))
// 使用规则编号1、2、3、4、5、6、7、8、9、11、12、13进行查重
(merge.handle(1,2,3,4,5,6,7,8,9,11,12,13))
```
###### **方式2**
```javascript
// 使用规则编号1进行查重
function handle1(){
merge.handle(1)
}
//方法调用
handle1();
// 使用规则编号1、2、3、4、5、6、7、8、9、11、12、13进行查重
function handle2(){
merge.handle(1,2,3,4,5,6,7,8,9,11,12,13)
}
//方法调用
handle2();
```
- 使用自定义查重规则:如需自定义规则,可基于现有规则扩展编写,也可完全使用自定义重复比较方法。
- #### 自定义规则使用示例
###### **方式1**
```javascript
// 基于现有规则扩展查重方式
({
// 查重方法名称必须是 isDuplicate,返回结果必须是布尔值
isDuplicate: function(record1, record2) {
//调用内置查重比对器comparator的isDuplicate方法查重,传递的三个参数分别是: record1, record2 和 规则编号
let duplicated = comparator.isDuplicate(record1, record2, 1);
//如果查重匹配
if(duplicated){
return duplicated;
}
//如果查重不匹配,则调用自定义的比对方法
// 注: func 为内置的函数
return func.equal(record1.title,record2.title);
}
})
```
###### **方式2**
```javascript
// 自定义查重规则编写
// 立即执行函数()传递一个json对象如下:
({
// 查重方法名称必须是 isDuplicate,返回结果必须是布尔值
isDuplicate: function(record1, record2) {
// 如果查重匹配
if(func.equal(record1.title,record2.title)){
return true;
}
// 如果查重不匹配,则调用自定义的比对方法 注:func 为内置的函数
// 判断是否包含相同作者
if(func.isNull(record1.author) || func.isNull(record2.author) ){
return false;
}
var authorList1 = func.str2List(record1.author)
var authorList2 = func.str2List(record2.author)
// 如果列表为空
if(func.isNull(authorList1) || func.isNull(authorList2) ){
return false;
}
for (var i = 0; i < authorList1.length; i++) {
for (var j = 0; j < authorList2.length; j++) {
if (func.equal(authorList1[i], authorList2[j])) {
return true;
}
}
var titleArray1 = record1.title.split("");
var titleArray2 = record2.title.split("");
// 如果字符串长度小于3
if (titleArray1.length < 3 || titleArray2.length < 3) {
return false;
}
// 判断记录2的题名是否以题名1的前两个字段相同 如果相同 则是同一条记录
return func.startWith(record2.title,titleArray1[0]+titleArray1[1]);
}
}})
```
### 内置参数说明
- #### Record 对象说明
在自定义函数中两个形参 record1 和 record1 为当前数据分区中的前一条记录和后一条记录。
| 字段名 | 类型 | 描述 |
|-------------------|---------------|-----------------------------------------|
| groupType | String | 分组类型 参数为:_ISBN_,_ISSN_,_UNI_,_TITLE_任一 |
| groupId | String | 分组id 如:100001 |
| groupKeys | String | 分组keys 如:100001,100002,100003(三个有交集) |
| tid | String | 特征id |
| title | String | 题名 |
| version | String | 版本 |
| mainTitle | String | 正题名 |
| otherTitle | String | 其他题名 |
| seriesNumber | String | 分辑号 |
| seriesName | String | 分辑名称 |
| author | String | 责任者 |
| publishingHouse | String | 出版者 |
| isbn | String | ISBN |
| issn | String | ISSN |
| unifiedBookNumber | String | 统一书刊号 |
| pageNumber | String | 页码 |
| resourceType | String | 资源类型 (普通图书,连续出版物,中文古籍,地图,乐谱) |
| publishTime | String | 出版日期 |
| dataLevel | Integer | 数据级别 |
| state | Integer | 状态 |
| createTime | LocalDateTime | 馆藏入库时间 |
| createBy | String | 创建者 |
| updateTime | LocalDateTime | 更新时间 |
| updateBy | String | 更新者 |
- #### func 函数说明
| 方法名 | 返回类型 | 参数 | 描述 |
|-------------------------|------------|-------------------------------|----------------------------------------------------------------------|
| isNotEmpty | boolean | (Collection<?> collection) | 检查集合是否不为空 |
| isNotEmpty | boolean | (String str) | 检查字符串是否不为空 |
| isNotEmpty | boolean | (Object[] array) | 检查数组是否不为空 |
| isNotNull | boolean | (Object obj) | 检查对象是否不为空 |
| isNull | boolean | (Object obj) | 检查对象是否为空 |
| isEmpty | boolean | (Collection<?> collection) | 检查集合是否为空 |
| isEmpty | T[] | (T[] array, T[] defaultValue) | 如果数组为空,则返回默认值,否则返回原数组 |
| isEmpty | boolean | (Map<?, ?> map) | 检查映射是否为空 |
| isEmpty | boolean | (String str) | 检查字符串是否为空 |
| equal | boolean | (Object obj1, Object obj2) | 检查两个对象是否相等 |
| notEqual | boolean | (Object obj1, Object obj2) | 检查两个对象是否不相等 |
| startWithIgnoreCase | boolean | (String str, String prefix) | 检查字符串是否以指定前缀(忽略大小写)开头 |
| startWith | boolean | (String str, String prefix) | 检查字符串是否以指定前缀开头 |
| endsWith | boolean | (String str, String suffix) | 检查字符串是否以指定后缀结尾 |
| endsWithIgnoreCase | boolean | (String str, String suffix) | 检查字符串是否以指定后缀(忽略大小写)结尾 |
| str2List | List<String>| (String str) | 将字符串按逗号分割成字符串列表,如果字符串为空则返回空列表 |
| list2Str | String | (Collection<String> collection) | 将字符串集合按逗号连接成字符串,如果集合为空则返回空字符串 |
| list2Str | String | (List<Object> list) | 将对象列表按逗号连接成字符串,如果列表为空则返回空字符串 |
- #### merge 函数说明
该方法用于调用内置查重查重比较函数,传递参数为 `strategyId`, 可传递多个 `strategyId`,strategyId 具体参数请对 [ [**内置查重规则**] ](#内置查重规则)。
- #### comparator 函数说明
该方法用于比较两个 `Record` 对象是否为重复项。比较策略由 `strategyId` 参数指定,两个 `Record` 对象根据指定的策略被认为是重复项,则返回 `true`;否则返回 `false`,如果提供的 `strategyId` 无效(即不在上述策略范围内),则抛出此异常。