Skip to content

Commit

Permalink
bg(search filter): added search and filter functionality [Finishes #1…
Browse files Browse the repository at this point in the history
…69191116]
  • Loading branch information
minega25 committed Oct 17, 2019
1 parent 8863da4 commit d0108c5
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 16 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.15",
"method-override": "^2.3.10",
"moment": "^2.24.0",
"multer": "^1.4.2",
"nyc": "^14.1.1",
"open": "^6.4.0",
Expand Down
44 changes: 29 additions & 15 deletions src/controllers/articles.controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dotenv/config';
import slug from 'slug';
import _ from 'lodash';
import moment from 'moment';
import uniqid from 'uniqid';
import models from '../models';
import Userservice from '../services/user.service';
Expand Down Expand Up @@ -68,14 +69,14 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} articles
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} articles
* @memberof Articles
*/
static async getAllArticles(req, res) {
const counter = await db.count();
if (req.offset >= counter) {
Expand All @@ -89,6 +90,7 @@ class Articles {
const allArticles = _.map(
articles,
_.partialRight(_.pick, [
'authorId',
'slug',
'title',
'description',
Expand All @@ -98,15 +100,26 @@ class Articles {
'favoritedcount',
'flagged',
'images',
'views'
'views',
'createdAt',
])
);

allArticles.map((article) => {
const readTime = Helper.calculateReadTime(article.body);
article.readtime = readTime;
return true;
});
await Promise.all(allArticles.map(async (article) => {
try {
const userDetails = await Userservice.getOneUser(article.authorId);
const { username, image } = userDetails;
const readTime = Helper.calculateReadTime(article.body);
const timeAgo = moment(article.createdAt).fromNow();
article.readtime = readTime;
article.username = username;
article.userImage = image;
article.timeCreated = timeAgo;
return true;
} catch (error) {
console.log(error);
}
}));
const popularArticles = allArticles.slice(0);
popularArticles.sort((a, b) => b.views - a.views);
const mostPopular = popularArticles.slice(0, 9);
Expand Down Expand Up @@ -142,6 +155,7 @@ class Articles {
message: 'That article does not exist!'
});
}

const article = _.pick(findArticle, [
'slug',
'title',
Expand All @@ -152,7 +166,7 @@ class Articles {
'favoritedcount',
'flagged',
'images',
'views'
'views',
]);
const readTime = Helper.calculateReadTime(article.body);
article.readtime = readTime;
Expand Down
83 changes: 83 additions & 0 deletions src/controllers/search.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import _ from 'lodash';
import moment from 'moment';
import ArticleModel from '../services/article.service';
import UserModel from '../services/user.service';
import TagModel from '../services/tag.service';
import Util from '../helpers/util';
import Helper from '../helpers/helper';

const util = new Util();
/**
*
*
* @class Report
*/
class Search {
/**
*
*
* @static
* @param {*} req
* @param {*} res
* @return {Json} return json object
* @memberof Search
*/
static async processSearchQuery(req, res) {
const { q, offset, limit } = req.query;
const searchQuery = JSON.parse(q);
const articles = await ArticleModel.searchArticle(searchQuery.keyword, offset, limit);
const foundArticles = _.map(
articles,
_.partialRight(_.pick, [
'authorId',
'slug',
'title',
'description',
'body',
'taglist',
'favorited',
'favoritedcount',
'flagged',
'images',
'views',
'createdAt',
])
);

await Promise.all(foundArticles.map(async (article) => {
try {
const userDetails = await UserModel.getOneUser(article.authorId);
const { username, image } = userDetails;
const readTime = Helper.calculateReadTime(article.body);
const timeAgo = moment(article.createdAt).fromNow();
article.readtime = readTime;
article.username = username;
article.userImage = image;
article.timeCreated = timeAgo;
return true;
} catch (error) {
console.log(error);
}
}));
const users = await UserModel.searchUser(searchQuery.user, offset, limit);
const foundUsers = _.map(
users,
_.partialRight(_.pick, [
'username',
'image',
'bio',
])
);
const tags = await TagModel.searchTag('Tag', searchQuery.tag, offset, limit);
const foundTags = _.map(
tags,
_.partialRight(_.pick, [
'name',
])
);
util.setSuccess(200, 'Search successful', { foundArticles, foundUsers, foundTags });
return util.send(res);
}
}

export default Search;
2 changes: 2 additions & 0 deletions src/routes/api/index.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import Comments from './comment/comments.route';
import notifications from './notifications/notification.route';
import tag from './tag/tag.routes';
import reports from './reports/reports.routes';
import search from './search/search.routes';

const router = express.Router();
router.use('/images', express.static(path.join(__dirname, 'images')));

router.use('/search', search);
router.use('/comments', Comments);
router.use(oauth);
router.use('/profile', profile);
Expand Down
2 changes: 1 addition & 1 deletion src/routes/api/profile/profile.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const router = express.Router();

router.get('/', validateToken, confirmEmaiAuth, ProfileController.getProfile);
router.get('/authors', validateToken, confirmEmaiAuth, ProfileController.getProfiles);
router.get('/:username', validateToken, confirmEmaiAuth, ProfileController.getProfile);
router.get('/:username', ProfileController.getProfile);
router.put('/', [validateToken, confirmEmaiAuth, connectMulti, profileVAlidator], ProfileController.updateProfile);


Expand Down
8 changes: 8 additions & 0 deletions src/routes/api/search/search.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express';
import Search from '../../../controllers/search.controller';

const router = express.Router();

router.get('/', Search.processSearchQuery);

export default router;
31 changes: 31 additions & 0 deletions src/services/article.service.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Sequelize } from 'sequelize';
import models from '../models';

const db = models.Article;
const highlightDb = models.Highlight;
const { Op } = Sequelize;


/**
Expand Down Expand Up @@ -70,6 +72,35 @@ class articleService {
throw error;
}
}

/**
*
*
* @static
* @param {*} keyword
* @param {*} offset
* @param {*} limit
* @param {*} fieldToupdate
* @returns {object} object
* @memberof articleService
*/
static async searchArticle(keyword, offset, limit) {
try {
const results = await db.findAll({
where: {
[Op.or]: [
{ title: { [Op.iLike]: `%${keyword}%` } },
{ description: { [Op.iLike]: `%${keyword}%` } },
{ body: { [Op.iLike]: `%${keyword}%` } }]
},
offset,
limit,
});
return results;
} catch (error) {
throw error;
}
}
// highlighting part

/**
Expand Down
18 changes: 18 additions & 0 deletions src/services/tag.service.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* eslint-disable require-jsdoc */
import { Sequelize } from 'sequelize';
import models from '../models';

const { Tag, Article, ArticleTag } = models;

const Models = { Article, Tag };
const { Op } = Sequelize;


class TagService {
Expand All @@ -20,6 +22,22 @@ class TagService {
});
}

static async searchTag(model, tag, offset, limit, include = null) {
try {
const results = await Models[model].findAll({
where: {
[Op.or]: [{ name: { [Op.iLike]: `%${tag}%` } }]
},
offset,
limit,
include,
});
return results;
} catch (error) {
throw error;
}
}

static async checkItem(id, model, include = null) {
return Models[model].findOne({
where: { id },
Expand Down
27 changes: 27 additions & 0 deletions src/services/user.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,33 @@ class UserService {
}
}

/**
*
*
* @static
* @param {*} user
* @param {*} fieldToupdate
* @returns {object} object
* @memberof articleService
*/
static async searchUser(user) {
try {
const results = await database.user.findAll({
where: {
[Op.or]: [
{ firstname: { [Op.iLike]: `%${user}%` } },
{ lastname: { [Op.iLike]: `%${user}%` } },
{ email: { [Op.iLike]: `%${user}%` } },
{ username: { [Op.iLike]: `%${user}%` } },
{ bio: { [Op.iLike]: `%${user}%` } }]
}
});
return results;
} catch (error) {
throw error;
}
}

/**
*
*
Expand Down

0 comments on commit d0108c5

Please sign in to comment.