|
@@ -314,6 +314,7 @@ class ElasticsearchDelegator {
|
|
|
body: page.revision.body,
|
|
body: page.revision.body,
|
|
|
// username: page.creator?.username, // available Node.js v14 and above
|
|
// username: page.creator?.username, // available Node.js v14 and above
|
|
|
username: page.creator != null ? page.creator.username : null,
|
|
username: page.creator != null ? page.creator.username : null,
|
|
|
|
|
+ comments: page.comments,
|
|
|
comment_count: page.commentCount,
|
|
comment_count: page.commentCount,
|
|
|
bookmark_count: bookmarkCount,
|
|
bookmark_count: bookmarkCount,
|
|
|
like_count: page.liker.length || 0,
|
|
like_count: page.liker.length || 0,
|
|
@@ -371,6 +372,7 @@ class ElasticsearchDelegator {
|
|
|
const Page = mongoose.model('Page');
|
|
const Page = mongoose.model('Page');
|
|
|
const { PageQueryBuilder } = Page;
|
|
const { PageQueryBuilder } = Page;
|
|
|
const Bookmark = mongoose.model('Bookmark');
|
|
const Bookmark = mongoose.model('Bookmark');
|
|
|
|
|
+ const Comment = mongoose.model('Comment');
|
|
|
const PageTagRelation = mongoose.model('PageTagRelation');
|
|
const PageTagRelation = mongoose.model('PageTagRelation');
|
|
|
|
|
|
|
|
const socket = this.socketIoService.getAdminSocket();
|
|
const socket = this.socketIoService.getAdminSocket();
|
|
@@ -431,6 +433,28 @@ class ElasticsearchDelegator {
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+ const appendCommentStream = new Transform({
|
|
|
|
|
+ objectMode: true,
|
|
|
|
|
+ async transform(chunk, encoding, callback) {
|
|
|
|
|
+ const pageIds = chunk.map(doc => doc._id);
|
|
|
|
|
+
|
|
|
|
|
+ const idToCommentMap = await Comment.getPageIdToCommentMap(pageIds);
|
|
|
|
|
+ const idsHavingComment = Object.keys(idToCommentMap);
|
|
|
|
|
+
|
|
|
|
|
+ // append comments
|
|
|
|
|
+ chunk
|
|
|
|
|
+ .filter(doc => idsHavingComment.includes(doc._id.toString()))
|
|
|
|
|
+ .forEach((doc) => {
|
|
|
|
|
+ // append comments from idToCommentMap
|
|
|
|
|
+ doc.comments = idToCommentMap[doc._id.toString()];
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.push(chunk);
|
|
|
|
|
+ callback();
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
const appendTagNamesStream = new Transform({
|
|
const appendTagNamesStream = new Transform({
|
|
|
objectMode: true,
|
|
objectMode: true,
|
|
|
async transform(chunk, encoding, callback) {
|
|
async transform(chunk, encoding, callback) {
|
|
@@ -503,6 +527,7 @@ class ElasticsearchDelegator {
|
|
|
.pipe(thinOutStream)
|
|
.pipe(thinOutStream)
|
|
|
.pipe(batchStream)
|
|
.pipe(batchStream)
|
|
|
.pipe(appendBookmarkCountStream)
|
|
.pipe(appendBookmarkCountStream)
|
|
|
|
|
+ .pipe(appendCommentStream)
|
|
|
.pipe(appendTagNamesStream)
|
|
.pipe(appendTagNamesStream)
|
|
|
.pipe(writeStream);
|
|
.pipe(writeStream);
|
|
|
|
|
|
|
@@ -579,7 +604,7 @@ class ElasticsearchDelegator {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
createSearchQuerySortedByScore(option) {
|
|
createSearchQuerySortedByScore(option) {
|
|
|
- let fields = ['path', 'bookmark_count', 'comment_count', 'updated_at', 'tag_names'];
|
|
|
|
|
|
|
+ let fields = ['path', 'bookmark_count', 'comment_count', 'updated_at', 'tag_names', 'comments'];
|
|
|
if (option) {
|
|
if (option) {
|
|
|
fields = option.fields || fields;
|
|
fields = option.fields || fields;
|
|
|
}
|
|
}
|
|
@@ -635,7 +660,7 @@ class ElasticsearchDelegator {
|
|
|
multi_match: {
|
|
multi_match: {
|
|
|
query: parsedKeywords.match.join(' '),
|
|
query: parsedKeywords.match.join(' '),
|
|
|
type: 'most_fields',
|
|
type: 'most_fields',
|
|
|
- fields: ['path.ja^2', 'path.en^2', 'body.ja', 'body.en'],
|
|
|
|
|
|
|
+ fields: ['path.ja^2', 'path.en^2', 'body.ja', 'body.en', 'comments.ja', 'comments.en'],
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
query.body.query.bool.must.push(q);
|
|
query.body.query.bool.must.push(q);
|
|
@@ -645,7 +670,7 @@ class ElasticsearchDelegator {
|
|
|
const q = {
|
|
const q = {
|
|
|
multi_match: {
|
|
multi_match: {
|
|
|
query: parsedKeywords.not_match.join(' '),
|
|
query: parsedKeywords.not_match.join(' '),
|
|
|
- fields: ['path.ja', 'path.en', 'body.ja', 'body.en'],
|
|
|
|
|
|
|
+ fields: ['path.ja', 'path.en', 'body.ja', 'body.en', 'comments.ja', 'comments.en'],
|
|
|
operator: 'or',
|
|
operator: 'or',
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
@@ -657,12 +682,13 @@ class ElasticsearchDelegator {
|
|
|
parsedKeywords.phrase.forEach((phrase) => {
|
|
parsedKeywords.phrase.forEach((phrase) => {
|
|
|
phraseQueries.push({
|
|
phraseQueries.push({
|
|
|
multi_match: {
|
|
multi_match: {
|
|
|
- query: phrase, // each phrase is quoteted words
|
|
|
|
|
|
|
+ query: phrase, // each phrase is quoteted words like "This is GROWI"
|
|
|
type: 'phrase',
|
|
type: 'phrase',
|
|
|
fields: [
|
|
fields: [
|
|
|
// Not use "*.ja" fields here, because we want to analyze (parse) search words
|
|
// Not use "*.ja" fields here, because we want to analyze (parse) search words
|
|
|
'path.raw^2',
|
|
'path.raw^2',
|
|
|
'body',
|
|
'body',
|
|
|
|
|
+ 'comments',
|
|
|
],
|
|
],
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
@@ -1023,6 +1049,12 @@ class ElasticsearchDelegator {
|
|
|
return this.updateOrInsertPageById(pageId);
|
|
return this.updateOrInsertPageById(pageId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ async syncCommentChanged(comment) {
|
|
|
|
|
+ logger.debug('SearchClient.syncCommentChanged', comment);
|
|
|
|
|
+
|
|
|
|
|
+ return this.updateOrInsertPageById(comment.page);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
async syncTagChanged(page) {
|
|
async syncTagChanged(page) {
|
|
|
logger.debug('SearchClient.syncTagChanged', page.path);
|
|
logger.debug('SearchClient.syncTagChanged', page.path);
|
|
|
|
|
|