Authored by 郝肖肖

Merge branch 'feature/seo' into 'master'

随机关联词和显示小分类及大分类



See merge request !4
... ... @@ -99,6 +99,35 @@ const mgets = async(ctx, item) => {
});
};
//通过小分类同步中分类和大分类
const getMsort = async(ctx) => {
let redis = ctx.redis;
return redis.getAsync(`global:yoho:sorts`).then((sorts) => {
let sData = {};
sorts = JSON.parse(sorts) || [];
_.forEach(_.get(sorts, 'data.sort'), (msort) => {
_.forEach(_.get(msort, 'sub'), (misort) => {
_.forEach(_.get(misort, 'sub'), (sort) => {
if (!sData[sort.sort_id]) {
sData[sort.sort_id] = {
msort: msort.sort_id,
msort_name: msort.sort_name,
misort: misort.sort_id,
misort_name: misort.sort_name,
sort_id: sort.sort_id,
sort_name: sort.sort_name,
};
}
})
})
})
return sData;
});
};
r.get('/', async(ctx) => {
let resData = {};
let q = ctx.request.query,
... ... @@ -301,10 +330,6 @@ r.get('/expand', async(ctx) => {
resData.pager = pager(Math.floor((total - 1) / limit) + 1, ctx.query);
_.each(d, (val) => {
if (val.sort_id) {
sortIds.push(`${singleSortKeyPre}${val.sort_id}`);
}
if (val.brand_id) {
brandIds.push(`${singleBrandKeyPre}${val.brand_id}`);
}
... ... @@ -315,14 +340,16 @@ r.get('/expand', async(ctx) => {
});
brandIds = await mgets(ctx, brandIds);
sortIds = await mgets(ctx, sortIds);
sortIds = await getMsort(ctx);
rootIds = await getRootKeyword(rootIds, mysql);
resData.tabs = _.map(d, (elem) => {
return Object.assign({}, elem, {
root: rootIds[elem.root_id],
brand: brandIds[`${singleBrandKeyPre}${elem.brand_id}`],
sort: sortIds[`${singleSortKeyPre}${elem.sort_id}`],
sort: sortIds[elem.sort_id] && sortIds[elem.sort_id].sort_name,
misort: sortIds[elem.sort_id] && sortIds[elem.sort_id].misort_name,
msort: sortIds[elem.sort_id] && sortIds[elem.sort_id].msort_name,
is_push: elem.is_push ? '是' : '否',
add_time: elem.add_time && moment(elem.add_time * 1000).format('YYYY-MM-DD HH:mm'),
});
... ... @@ -372,7 +399,7 @@ r.post('/expand/del', async(ctx) => {
* @return {[type]} [description]
*/
r.post('/expand/randWords', async(ctx) => {
let key = `golobal:yoho:seo:keywords:isRun`;
let key = `global:yoho:seo:keywords:isRun`;
return ctx.redis.getAsync(key).then((d) => {
... ...
... ... @@ -6,10 +6,10 @@ const MysqlPromise = require('../../../lib/mysql-promise');
const Promise = require('bluebird');
const keywordsRedis = {
'keywordsAllIds': `golobal:yoho:seo:keywords:allIds`,// 关键词表符合条件所有id
'keywordsSortId': `golobal:yoho:seo:keywords:sortId`,// 分类下的所有关键词
'keywordsId': `golobal:yoho:seo:keywords:id`,// 每条关键词关联其它12条关键词
'keywordsIsRun': `golobal:yoho:seo:keywords:isRun`,// 判断是否正在执行中
'keywordsAllIds': `global:yoho:seo:keywords:allIds`,// 关键词表符合条件所有id
'keywordsSortId': `global:yoho:seo:keywords:sortId`,// 分类下的所有关键词
'keywordsId': `global:yoho:seo:keywords:id`,// 每条关键词关联其它12条关键词
'keywordsIsRun': `global:yoho:seo:keywords:isRun`,// 判断是否正在执行中
};
class expandModel extends model {
... ... @@ -22,59 +22,131 @@ class expandModel extends model {
}
getRanData() {
this.dataIds = [];
return this.redis.setAsync(`${keywordsRedis.keywordsIsRun}`, 1).then(() => {// 设置正在运行的key
return this.redis.expireAsync(`${keywordsRedis.keywordsIsRun}`, 5 * 60);// 设置正在运行的key有效期
return this.redis.expireAsync(`${keywordsRedis.keywordsIsRun}`, 10800);// 设置正在运行的key有效期
}).then(() => {
return this.mysql.query(`SELECT sort_id FROM seo_keywords WHERE status = 1 GROUP BY sort_id;`);
return this.sortIdInit();
}).then(rdata => {
return Promise.each(rdata, (item) => this._setSortToRedis(item.sort_id));
}).then(d => {
return this.redis.setAsync(`${keywordsRedis.keywordsAllIds}`, JSON.stringify(this.dataIds));
}).then(d => {
this.redis.delAsync(`${keywordsRedis.keywordsIsRun}`);
return this.msortInit();
}).then(() => {
return this.allIdsExec(1);
}).then(() => {
return this.redis.delAsync(`${keywordsRedis.keywordsIsRun}`);
}).then(() => {
return true;
});
}
this.dataIds = [];
return d;
//处理小分类function
sortIdInit() {
return this.mysql.query(`SELECT sort_id FROM seo_keywords WHERE status = 1 AND sort_id > 0 GROUP BY sort_id;`).then(rdata => {
return Promise.each(rdata, (item) => this.sortIdExec(item.sort_id, 1));
});
}
sortIdExec(sortId, page) {
let pageSize = 1000;
let pageStart = (page - 1) * pageSize;
return this.sleep(5000).then(() => {
return this.mysql.query(`SELECT id, keyword, root_id, brand_id, sort_id FROM seo_keywords WHERE status = 1 AND yoho_goods_num > 3 AND sort_id=${sortId} LIMIT ${pageStart}, ${pageSize};`);
}).then(dsort => {
if (dsort.length <= 0) {
return false;
}
_setSortToRedis(sortId) {
return this.mysql.query(`SELECT id, keyword, root_id, brand_id, sort_id FROM seo_keywords WHERE status = 1 AND yoho_goods_num > 3 AND sort_id=${sortId};`).then(dsort => {
let len = dsort.length;
let key;
let tdata;
return this.execRandData(dsort).then(() => {
return this.redis.setAsync(`${keywordsRedis.keywordsSortId}:${sortId}:page:${page}`, JSON.stringify(dsort));
}).then(() => {
dsort = [];
return this.sortIdExec(sortId, ++page);
});
});
}
if (len <= 0) {
return Promise.resolve(true);
//处理小分类为0且大分类>=0的function
msortInit() {
return this.mysql.query(`SELECT msort FROM seo_keywords WHERE status = 1 AND sort_id = 0 GROUP BY msort;`).then(rdata => {
return Promise.each(rdata, (item) => this.msortExec(item.msort, 1));
});
}
msortExec(sortId, page) {
let pageSize = 1000;
let pageStart = (page - 1) * pageSize;
return this.sleep(5000).then(() => {
return this.mysql.query(`SELECT id, keyword, root_id, brand_id, sort_id FROM seo_keywords WHERE status = 1 AND sort_id = 0 AND yoho_goods_num > 3 AND msort=${sortId} LIMIT ${pageStart}, ${pageSize};`);
}).then(dsort => {
if (dsort.length <= 0) {
return false;
}
return this.redis.setAsync(`${keywordsRedis.keywordsSortId}:${sortId}`, JSON.stringify(dsort)).then(() => {
return Promise.each(dsort, (el, index) => {
key = `${keywordsRedis.keywordsId}:${el.id}`;
/**
* 1、小分类为0且大分类大于0,要随机关联12词
* 2、小分类为0且大分类小于0,不要随机关联12个词。即大分类和小分类都为0的情况,data: [];
*/
return this.execRandData(dsort).then(() => {
dsort = [];
return this.msortExec(sortId, ++page);
});
});
}
//随机关联12个关键词
execRandData(dsort) {
let len = dsort.length;
let key;
let tdata;
if (len <= 0) {
return Promise.resolve(false);
}
return Promise.each(dsort, (el, index) => {
key = `${keywordsRedis.keywordsId}:${el.id}`;
tdata = {
name: el.keyword,
data: _.compact(_.map(this.getRandom(dsort, index), (mval) => {
return dsort[mval];
})) || []
};
console.log(`execRandData, index: ${index}, len: ${len}, id: ${el.id}, keywords: ${el.keyword}, key: ${key}`);
return this.redis.setAsync(key, JSON.stringify(tdata));
});
}
getRandom(dsort, index) {
return _.shuffle(_.difference(_.keys(dsort), [`${index}`])).slice(0, 12);
}
//符合条件和关键词设置redis中
allIdsExec(page) {
let pageSize = 40000;
let pageStart = (page - 1) * pageSize;
this.dataIds.push(el.id);
return this.mysql.query(`SELECT id FROM seo_keywords WHERE status = 1 AND yoho_goods_num > 3 LIMIT ${pageStart}, ${pageSize};`).then(dsort => {
if (dsort.length <= 0) {
return false;
}
tdata = {
name: el.keyword,
data: _.compact(_.map(this._getRandom(dsort, index), (mval) => {
return dsort[mval];
}))
};
let ids = _.map(dsort, (sort) => {
return sort.id;
});
console.log(`setSortToRedis, index: ${index}, len: ${len}, id: ${el.id}, keywords: ${el.keyword}, key: ${key}`);
return this.redis.setAsync(key, JSON.stringify(tdata));
});
}).then((d) => {
return this.redis.setAsync(`${keywordsRedis.keywordsAllIds}:page:${page}`, JSON.stringify(ids)).then(() => {
dsort = [];
return true;
ids = [];
return this.allIdsExec(++page);
});
});
}
_getRandom(dsort, index) {
return _.shuffle(_.difference(_.keys(dsort), [`${index}`])).slice(0, 12);
sleep(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, time);
});
}
}
... ...
... ... @@ -69,7 +69,8 @@
<th>关键词</th>
<th>词根</th>
<th>品牌</th>
<th>品类</th>
<th>小品类</th>
<th>大品类</th>
<th>商品数</th>
<th>是否推送</th>
<th>添加时间</th>
... ... @@ -94,6 +95,9 @@
{{sort}}
</td>
<td>
{{msort}}
</td>
<td>
{{yoho_goods_num}}
</td>
<td>
... ...