mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-12 17:05:51 +01:00
closes #6932
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
"at-most": "At most",
|
"at-most": "At most",
|
||||||
"relevance": "Relevance",
|
"relevance": "Relevance",
|
||||||
"post-time": "Post time",
|
"post-time": "Post time",
|
||||||
|
"votes": "Votes",
|
||||||
"newer-than": "Newer than",
|
"newer-than": "Newer than",
|
||||||
"older-than": "Older than",
|
"older-than": "Older than",
|
||||||
"any-date": "Any date",
|
"any-date": "Any date",
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
"sort-by": "Sort by",
|
"sort-by": "Sort by",
|
||||||
"last-reply-time": "Last reply time",
|
"last-reply-time": "Last reply time",
|
||||||
"topic-title": "Topic title",
|
"topic-title": "Topic title",
|
||||||
|
"topic-votes": "Topic votes",
|
||||||
"number-of-replies": "Number of replies",
|
"number-of-replies": "Number of replies",
|
||||||
"number-of-views": "Number of views",
|
"number-of-views": "Number of views",
|
||||||
"topic-start-date": "Topic start date",
|
"topic-start-date": "Topic start date",
|
||||||
|
|||||||
@@ -116,8 +116,8 @@ define('forum/search', ['search', 'autocomplete', 'storage'], function (searchMo
|
|||||||
|
|
||||||
if (formData.sortBy || ajaxify.data.searchDefaultSortBy) {
|
if (formData.sortBy || ajaxify.data.searchDefaultSortBy) {
|
||||||
$('#post-sort-by').val(formData.sortBy || ajaxify.data.searchDefaultSortBy);
|
$('#post-sort-by').val(formData.sortBy || ajaxify.data.searchDefaultSortBy);
|
||||||
$('#post-sort-direction').val(formData.sortDirection);
|
|
||||||
}
|
}
|
||||||
|
$('#post-sort-direction').val(formData.sortDirection || 'desc');
|
||||||
|
|
||||||
if (formData.showAs) {
|
if (formData.showAs) {
|
||||||
var isTopic = formData.showAs === 'topics';
|
var isTopic = formData.showAs === 'topics';
|
||||||
|
|||||||
124
src/search.js
124
src/search.js
@@ -46,12 +46,8 @@ function searchInContent(data, callback) {
|
|||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
searchCids: function (next) {
|
searchCids: async.apply(getSearchCids, data),
|
||||||
getSearchCids(data, next);
|
searchUids: async.apply(getSearchUids, data),
|
||||||
},
|
|
||||||
searchUids: function (next) {
|
|
||||||
getSearchUids(data, next);
|
|
||||||
},
|
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
@@ -70,12 +66,8 @@ function searchInContent(data, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
async.parallel({
|
async.parallel({
|
||||||
pids: function (next) {
|
pids: async.apply(doSearch, 'post', ['posts', 'titlesposts']),
|
||||||
doSearch('post', ['posts', 'titlesposts'], next);
|
tids: async.apply(doSearch, 'topic', ['titles', 'titlesposts']),
|
||||||
},
|
|
||||||
tids: function (next) {
|
|
||||||
doSearch('topic', ['titles', 'titlesposts'], next);
|
|
||||||
},
|
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
@@ -150,16 +142,16 @@ function filterAndSort(pids, data, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getMatchedPosts(pids, data, callback) {
|
function getMatchedPosts(pids, data, callback) {
|
||||||
var postFields = ['pid', 'uid', 'tid', 'timestamp', 'deleted'];
|
var postFields = ['pid', 'uid', 'tid', 'timestamp', 'deleted', 'upvotes', 'downvotes'];
|
||||||
var categoryFields = [];
|
var categoryFields = [];
|
||||||
|
|
||||||
if (data.sortBy && data.sortBy !== 'relevance') {
|
if (data.sortBy && data.sortBy.startsWith('category.')) {
|
||||||
if (data.sortBy.startsWith('category.')) {
|
|
||||||
categoryFields.push(data.sortBy.split('.')[1]);
|
categoryFields.push(data.sortBy.split('.')[1]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var postsData;
|
var postsData;
|
||||||
|
let tids;
|
||||||
|
let uids;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
posts.getPostsFields(pids, postFields, next);
|
posts.getPostsFields(pids, postFields, next);
|
||||||
@@ -170,7 +162,7 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
async.parallel({
|
async.parallel({
|
||||||
users: function (next) {
|
users: function (next) {
|
||||||
if (data.sortBy && data.sortBy.startsWith('user')) {
|
if (data.sortBy && data.sortBy.startsWith('user')) {
|
||||||
var uids = postsData.map(post => post.uid);
|
uids = _.uniq(postsData.map(post => post.uid));
|
||||||
user.getUsersFields(uids, ['username'], next);
|
user.getUsersFields(uids, ['username'], next);
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
@@ -178,7 +170,8 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
},
|
},
|
||||||
topics: function (next) {
|
topics: function (next) {
|
||||||
var topicsData;
|
var topicsData;
|
||||||
const tids = postsData.map(post => post.tid);
|
tids = _.uniq(postsData.map(post => post.tid));
|
||||||
|
let cids;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
topics.getTopicsData(tids, next);
|
topics.getTopicsData(tids, next);
|
||||||
@@ -186,20 +179,13 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
function (_topics, next) {
|
function (_topics, next) {
|
||||||
topicsData = _topics;
|
topicsData = _topics;
|
||||||
async.parallel({
|
async.parallel({
|
||||||
teasers: function (next) {
|
|
||||||
if (data.sortBy && data.sortBy.startsWith('teaser')) {
|
|
||||||
var teaserKeys = topicsData.map(topic => 'post:' + topic.teaserPid);
|
|
||||||
db.getObjectsFields(teaserKeys, ['timestamp'], next);
|
|
||||||
} else {
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
categories: function (next) {
|
categories: function (next) {
|
||||||
if (!categoryFields.length) {
|
if (!categoryFields.length) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
var cids = topicsData.map(topic => 'category:' + topic.cid);
|
|
||||||
db.getObjectsFields(cids, categoryFields, next);
|
cids = _.uniq(topicsData.map(topic => topic && topic.cid));
|
||||||
|
db.getObjectsFields(cids.map(cid => 'category:' + cid), categoryFields, next);
|
||||||
},
|
},
|
||||||
tags: function (next) {
|
tags: function (next) {
|
||||||
if (Array.isArray(data.hasTags) && data.hasTags.length) {
|
if (Array.isArray(data.hasTags) && data.hasTags.length) {
|
||||||
@@ -211,12 +197,10 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
|
const cidToCategory = _.zipObject(cids, results.categories);
|
||||||
topicsData.forEach(function (topic, index) {
|
topicsData.forEach(function (topic, index) {
|
||||||
if (topic && results.categories && results.categories[index]) {
|
if (topic && results.categories && cidToCategory[topic.cid]) {
|
||||||
topic.category = results.categories[index];
|
topic.category = cidToCategory[topic.cid];
|
||||||
}
|
|
||||||
if (topic && results.teasers && results.teasers[index]) {
|
|
||||||
topic.teaser = results.teasers[index];
|
|
||||||
}
|
}
|
||||||
if (topic && results.tags && results.tags[index]) {
|
if (topic && results.tags && results.tags[index]) {
|
||||||
topic.tags = results.tags[index];
|
topic.tags = results.tags[index];
|
||||||
@@ -230,19 +214,18 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
postsData.forEach(function (post, index) {
|
const tidToTopic = _.zipObject(tids, results.topics);
|
||||||
if (results.topics && results.topics[index]) {
|
const uidToUser = _.zipObject(uids, results.users);
|
||||||
post.topic = results.topics[index];
|
postsData.forEach(function (post) {
|
||||||
if (results.topics[index].category) {
|
if (results.topics && tidToTopic[post.tid]) {
|
||||||
post.category = results.topics[index].category;
|
post.topic = tidToTopic[post.tid];
|
||||||
}
|
if (post.topic && post.topic.category) {
|
||||||
if (results.topics[index].teaser) {
|
post.category = post.topic.category;
|
||||||
post.teaser = results.topics[index].teaser;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.users && results.users[index]) {
|
if (uidToUser[post.uid]) {
|
||||||
post.user = results.users[index];
|
post.user = uidToUser[post.uid];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -256,13 +239,9 @@ function filterByPostcount(posts, postCount, repliesFilter) {
|
|||||||
postCount = parseInt(postCount, 10);
|
postCount = parseInt(postCount, 10);
|
||||||
if (postCount) {
|
if (postCount) {
|
||||||
if (repliesFilter === 'atleast') {
|
if (repliesFilter === 'atleast') {
|
||||||
posts = posts.filter(function (post) {
|
posts = posts.filter(post => post.topic && post.topic.postcount >= postCount);
|
||||||
return post.topic && post.topic.postcount >= postCount;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
posts = posts.filter(function (post) {
|
posts = posts.filter(post => post.topic && post.topic.postcount <= postCount);
|
||||||
return post.topic && post.topic.postcount <= postCount;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return posts;
|
return posts;
|
||||||
@@ -271,15 +250,11 @@ function filterByPostcount(posts, postCount, repliesFilter) {
|
|||||||
function filterByTimerange(posts, timeRange, timeFilter) {
|
function filterByTimerange(posts, timeRange, timeFilter) {
|
||||||
timeRange = parseInt(timeRange, 10) * 1000;
|
timeRange = parseInt(timeRange, 10) * 1000;
|
||||||
if (timeRange) {
|
if (timeRange) {
|
||||||
var time = Date.now() - timeRange;
|
const time = Date.now() - timeRange;
|
||||||
if (timeFilter === 'newer') {
|
if (timeFilter === 'newer') {
|
||||||
posts = posts.filter(function (post) {
|
posts = posts.filter(post => post.timestamp >= time);
|
||||||
return post.timestamp >= time;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
posts = posts.filter(function (post) {
|
posts = posts.filter(post => post.timestamp <= time);
|
||||||
return post.timestamp <= time;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return posts;
|
return posts;
|
||||||
@@ -290,9 +265,7 @@ function filterByTags(posts, hasTags) {
|
|||||||
posts = posts.filter(function (post) {
|
posts = posts.filter(function (post) {
|
||||||
var hasAllTags = false;
|
var hasAllTags = false;
|
||||||
if (post && post.topic && Array.isArray(post.topic.tags) && post.topic.tags.length) {
|
if (post && post.topic && Array.isArray(post.topic.tags) && post.topic.tags.length) {
|
||||||
hasAllTags = hasTags.every(function (tag) {
|
hasAllTags = hasTags.every(tag => post.topic.tags.includes(tag));
|
||||||
return post.topic.tags.includes(tag);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return hasAllTags;
|
return hasAllTags;
|
||||||
});
|
});
|
||||||
@@ -307,18 +280,12 @@ function sortPosts(posts, data) {
|
|||||||
|
|
||||||
data.sortDirection = data.sortDirection || 'desc';
|
data.sortDirection = data.sortDirection || 'desc';
|
||||||
var direction = data.sortDirection === 'desc' ? 1 : -1;
|
var direction = data.sortDirection === 'desc' ? 1 : -1;
|
||||||
|
const fields = data.sortBy.split('.');
|
||||||
if (data.sortBy === 'timestamp') {
|
if (fields.length === 1) {
|
||||||
posts.sort(function (p1, p2) {
|
return posts.sort((p1, p2) => direction * (p2[fields[0]] - p1[fields[0]]));
|
||||||
return direction * (p2.timestamp - p1.timestamp);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstPost = posts[0];
|
var firstPost = posts[0];
|
||||||
var fields = data.sortBy.split('.');
|
|
||||||
|
|
||||||
if (!fields || fields.length !== 2 || !firstPost[fields[0]] || !firstPost[fields[0]][fields[1]]) {
|
if (!fields || fields.length !== 2 || !firstPost[fields[0]] || !firstPost[fields[0]][fields[1]]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -326,9 +293,7 @@ function sortPosts(posts, data) {
|
|||||||
var isNumeric = utils.isNumber(firstPost[fields[0]][fields[1]]);
|
var isNumeric = utils.isNumber(firstPost[fields[0]][fields[1]]);
|
||||||
|
|
||||||
if (isNumeric) {
|
if (isNumeric) {
|
||||||
posts.sort(function (p1, p2) {
|
posts.sort((p1, p2) => direction * (p2[fields[0]][fields[1]] - p1[fields[0]][fields[1]]));
|
||||||
return direction * (p2[fields[0]][fields[1]] - p1[fields[0]][fields[1]]);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
posts.sort(function (p1, p2) {
|
posts.sort(function (p1, p2) {
|
||||||
if (p1[fields[0]][fields[1]] > p2[fields[0]][fields[1]]) {
|
if (p1[fields[0]][fields[1]] > p2[fields[0]][fields[1]]) {
|
||||||
@@ -370,8 +335,7 @@ function getSearchCids(data, callback) {
|
|||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
var cids = results.watchedCids.concat(results.childrenCids).concat(data.categories).filter(Boolean);
|
const cids = _.uniq(results.watchedCids.concat(results.childrenCids).concat(data.categories).filter(Boolean));
|
||||||
cids = _.uniq(cids);
|
|
||||||
next(null, cids);
|
next(null, cids);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
@@ -380,18 +344,10 @@ function getSearchCids(data, callback) {
|
|||||||
function getChildrenCids(cids, uid, callback) {
|
function getChildrenCids(cids, uid, callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
categories.getChildren(cids, uid, next);
|
async.map(cids, categories.getChildrenCids, next);
|
||||||
},
|
},
|
||||||
function (childrenCategories, next) {
|
function (childrenCids, next) {
|
||||||
var childrenCids = [];
|
privileges.categories.filterCids('find', _.uniq(_.flatten(childrenCids)), uid, next);
|
||||||
var allCategories = [];
|
|
||||||
|
|
||||||
childrenCategories.forEach(function (childrens) {
|
|
||||||
categories.flattenCategories(allCategories, childrens);
|
|
||||||
childrenCids = childrenCids.concat(allCategories.map(category => category && category.cid));
|
|
||||||
});
|
|
||||||
|
|
||||||
next(null, childrenCids);
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,9 +255,7 @@ module.exports = function (Topics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.getTopicsTags = function (tids, callback) {
|
Topics.getTopicsTags = function (tids, callback) {
|
||||||
var keys = tids.map(function (tid) {
|
const keys = tids.map(tid => 'topic:' + tid + ':tags');
|
||||||
return 'topic:' + tid + ':tags';
|
|
||||||
});
|
|
||||||
db.getSetsMembers(keys, callback);
|
db.getSetsMembers(keys, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -268,9 +266,7 @@ module.exports = function (Topics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.getTopicsTagsObjects = function (tids, callback) {
|
Topics.getTopicsTagsObjects = function (tids, callback) {
|
||||||
var sets = tids.map(function (tid) {
|
const sets = tids.map(tid => 'topic:' + tid + ':tags');
|
||||||
return 'topic:' + tid + ':tags';
|
|
||||||
});
|
|
||||||
var uniqueTopicTags;
|
var uniqueTopicTags;
|
||||||
var topicTags;
|
var topicTags;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|||||||
@@ -125,10 +125,12 @@
|
|||||||
<select id="post-sort-by" class="form-control" data-field="searchDefaultSortBy">
|
<select id="post-sort-by" class="form-control" data-field="searchDefaultSortBy">
|
||||||
<option value="relevance">[[search:relevance]]</option>
|
<option value="relevance">[[search:relevance]]</option>
|
||||||
<option value="timestamp">[[search:post-time]]</option>
|
<option value="timestamp">[[search:post-time]]</option>
|
||||||
<option value="teaser.timestamp">[[search:last-reply-time]]</option>
|
<option value="votes">[[search:votes]]</option>
|
||||||
|
<option value="topic.lastposttime">[[search:last-reply-time]]</option>
|
||||||
<option value="topic.title">[[search:topic-title]]</option>
|
<option value="topic.title">[[search:topic-title]]</option>
|
||||||
<option value="topic.postcount">[[search:number-of-replies]]</option>
|
<option value="topic.postcount">[[search:number-of-replies]]</option>
|
||||||
<option value="topic.viewcount">[[search:number-of-views]]</option>
|
<option value="topic.viewcount">[[search:number-of-views]]</option>
|
||||||
|
<option value="topic.votes">[[search:topic-votes]]</option>
|
||||||
<option value="topic.timestamp">[[search:topic-start-date]]</option>
|
<option value="topic.timestamp">[[search:topic-start-date]]</option>
|
||||||
<option value="user.username">[[search:username]]</option>
|
<option value="user.username">[[search:username]]</option>
|
||||||
<option value="category.name">[[search:category]]</option>
|
<option value="category.name">[[search:category]]</option>
|
||||||
|
|||||||
Reference in New Issue
Block a user