|
|
@@ -41,6 +41,38 @@ SearchClient.prototype.buildIndex = function(uri) {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+SearchClient.prototype.deleteIndex = function(uri) {
|
|
|
+ return this.client.indices.delete({
|
|
|
+ index: this.index_name,
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+SearchClient.prototype.prepareBodyForUpdate = function(body, page) {
|
|
|
+ if (!Array.isArray(body)) {
|
|
|
+ throw new Error('Body must be an array.');
|
|
|
+ }
|
|
|
+
|
|
|
+ var command = {
|
|
|
+ update: {
|
|
|
+ _index: this.index_name,
|
|
|
+ _type: 'pages',
|
|
|
+ _id: page._id.toString(),
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var document = {
|
|
|
+ path: page.path,
|
|
|
+ body: page.revision.body,
|
|
|
+ username: page.creator.username,
|
|
|
+ comment_count: page.commentCount,
|
|
|
+ like_count: page.liker.length || 0,
|
|
|
+ updated_at: page.updatedAt,
|
|
|
+ };
|
|
|
+
|
|
|
+ body.push(command);
|
|
|
+ body.push(document);
|
|
|
+};
|
|
|
+
|
|
|
SearchClient.prototype.prepareBodyForCreate = function(body, page) {
|
|
|
if (!Array.isArray(body)) {
|
|
|
throw new Error('Body must be an array.');
|
|
|
@@ -82,6 +114,20 @@ SearchClient.prototype.addPages = function(pages)
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+SearchClient.prototype.updatePages = function(pages)
|
|
|
+{
|
|
|
+ var self = this;
|
|
|
+ var body = [];
|
|
|
+
|
|
|
+ pages.map(function(page) {
|
|
|
+ self.prepareBodyForUpdate(body, page);
|
|
|
+ });
|
|
|
+
|
|
|
+ return this.client.bulk({
|
|
|
+ body: body,
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
SearchClient.prototype.addAllPages = function()
|
|
|
{
|
|
|
var self = this;
|
|
|
@@ -99,15 +145,13 @@ SearchClient.prototype.addAllPages = function()
|
|
|
|
|
|
debug('Prepare', doc);
|
|
|
self.prepareBodyForCreate(body, doc);
|
|
|
- //debug('Data received: ', doc.path, doc.liker.length, doc.revision.body);
|
|
|
}).on('error', function (err) {
|
|
|
+ // TODO: handle err
|
|
|
debug('Error stream:', err);
|
|
|
- // handle err
|
|
|
}).on('close', function () {
|
|
|
// all done
|
|
|
- debug('Close');
|
|
|
|
|
|
- debug('SEnd', body);
|
|
|
+ debug('Send', body);
|
|
|
// 最後に送信
|
|
|
self.client.bulk({ body: body, })
|
|
|
.then(function(res) {
|
|
|
@@ -121,112 +165,119 @@ SearchClient.prototype.addAllPages = function()
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-module.exports = SearchClient;
|
|
|
-
|
|
|
-/*
|
|
|
-
|
|
|
-
|
|
|
-SearchClient.prototype.deleteIndex = function() {
|
|
|
+SearchClient.prototype.createSearchQuerySortedByUpdatedAt = function()
|
|
|
+{
|
|
|
+ // default is only id field, sorted by updated_at
|
|
|
+ return {
|
|
|
+ index: this.index_name,
|
|
|
+ type: 'pages',
|
|
|
+ body: {
|
|
|
+ fields: ['_id'],
|
|
|
+ sort: [{ updated_at: { order: 'desc'}}],
|
|
|
+ query: {}, // query
|
|
|
+ }
|
|
|
+ };
|
|
|
};
|
|
|
-*/
|
|
|
|
|
|
-/*
|
|
|
-module.exports = function(crowi) {
|
|
|
- var elasticsearch = require('elasticsearch'),
|
|
|
- debug = require('debug')('crowi:lib:search'),
|
|
|
- Page = crowi.model('Page'),
|
|
|
- Config = crowi.model('Config'),
|
|
|
- config = crowi.getConfig(),
|
|
|
- TYPE_PAGE = 'page',
|
|
|
- SLOW_INTERVAL = 200, // 200ms interval.
|
|
|
- lib = {};
|
|
|
-
|
|
|
- // TODO: configurable
|
|
|
- var host = '127.0.0.1:9200';
|
|
|
- var index_name = 'crowi';
|
|
|
- var default_mapping_file = crowi.resourceDir + 'search/mappings.json';
|
|
|
-
|
|
|
- var client = new elasticsearch.Client({
|
|
|
- host: host,
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
- lib.deleteIndex = function() {
|
|
|
- return client.indices.delete({
|
|
|
- index: index_name
|
|
|
- });
|
|
|
+SearchClient.prototype.createSearchQuerySortedByScore = function()
|
|
|
+{
|
|
|
+ // sort by score
|
|
|
+ return {
|
|
|
+ index: this.index_name,
|
|
|
+ type: 'pages',
|
|
|
+ body: {
|
|
|
+ fields: ['_id'],
|
|
|
+ sort: [ {_score: { order: 'desc'} }],
|
|
|
+ query: {}, // query
|
|
|
+ }
|
|
|
};
|
|
|
+};
|
|
|
|
|
|
- lib.buildIndex = function() {
|
|
|
- return client.indices.create({
|
|
|
- index: index_name,
|
|
|
- body: require(default_mapping_file)
|
|
|
- });
|
|
|
+SearchClient.prototype.searchSuggest = function(keyword)
|
|
|
+{
|
|
|
+ var query = this.createSearchQuerySortedByScore();
|
|
|
+
|
|
|
+ query.body.query = {
|
|
|
+ bool: {
|
|
|
+ must: [
|
|
|
+ {
|
|
|
+ bool: {
|
|
|
+ should: [
|
|
|
+ {
|
|
|
+ match: {
|
|
|
+ 'path.raw': {
|
|
|
+ query: sprintf('*%s*', keyword),
|
|
|
+ operator: 'or'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ match: {
|
|
|
+ 'body.ja': {
|
|
|
+ query: keyword,
|
|
|
+ operator: 'or'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
- lib.rebuildIndex = function() {
|
|
|
- var self = this;
|
|
|
+ return this.client.search(query);
|
|
|
+};
|
|
|
|
|
|
- return self.deleteIndex()
|
|
|
- .then(function(data) {
|
|
|
- return self.buildIndex();
|
|
|
- });
|
|
|
+SearchClient.prototype.searchKeyword = function(keyword)
|
|
|
+{
|
|
|
+ var query = this.createSearchQuerySortedByUpdatedAt();
|
|
|
+
|
|
|
+ query.body.query = {
|
|
|
+ bool: {
|
|
|
+ must: [
|
|
|
+ {
|
|
|
+ bool: {
|
|
|
+ should: [
|
|
|
+ {
|
|
|
+ match: {
|
|
|
+ 'path.raw': {
|
|
|
+ query: sprintf('*%s*', keyword),
|
|
|
+ operator: 'or'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ match: {
|
|
|
+ 'body.ja': {
|
|
|
+ query: keyword,
|
|
|
+ operator: 'or'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
- lib.addAllPages = function() {
|
|
|
- var offset = 0;
|
|
|
- var stream = Page.getStreamOfFindAll();
|
|
|
- var self = this;
|
|
|
-
|
|
|
- stream.on('data', function (doc) {
|
|
|
- if (!doc.creator || !doc.revision) {
|
|
|
- debug('Skipped', doc.path);
|
|
|
- return ;
|
|
|
- }
|
|
|
-
|
|
|
- var likeCount = doc.liker.length;
|
|
|
- var bookmarkCount = 0; // TODO
|
|
|
- var updated = doc.updatedAt; // TODO
|
|
|
-
|
|
|
- self.addPage(doc._id.toString(), doc.path, doc.revision.body, doc.creator.username, likeCount, bookmarkCount, updated, true)
|
|
|
- .then(function(data) {
|
|
|
- debug('Page Added', data);
|
|
|
- }).catch(function (err) {
|
|
|
- debug('Error addPage:', err);
|
|
|
- });
|
|
|
-
|
|
|
- //debug('Data received: ', doc.path, doc.liker.length, doc.revision.body);
|
|
|
- }).on('error', function (err) {
|
|
|
- debug('Error stream:', err);
|
|
|
- // handle err
|
|
|
- }).on('close', function () {
|
|
|
- debug('Close');
|
|
|
- // all done
|
|
|
- });
|
|
|
- };
|
|
|
+ return this.client.search(query);
|
|
|
+};
|
|
|
|
|
|
- lib.addPage = function(id, path, body, creator, likeCount, bookmarkCount, updated, is_public) {
|
|
|
- var self = this;
|
|
|
+SearchClient.prototype.searchByPath = function(keyword, prefix)
|
|
|
+{
|
|
|
+ var query = this.createSearchQuerySortedByUpdatedAt();
|
|
|
+};
|
|
|
|
|
|
- return client.create({
|
|
|
- index: index_name,
|
|
|
- type: 'page',
|
|
|
- id: id,
|
|
|
- body: {
|
|
|
- path: path,
|
|
|
- body: body,
|
|
|
- creator: creator,
|
|
|
- likeCount: likeCount,
|
|
|
- bookmarkCount: bookmarkCount,
|
|
|
- is_public: is_public,
|
|
|
- updated: updated,
|
|
|
- }
|
|
|
- });
|
|
|
+SearchClient.prototype.searchKeywordUnderPath = function(keyword, path)
|
|
|
+{
|
|
|
+ var query = this.createSearchQuerySortedByUpdatedAt();
|
|
|
+};
|
|
|
|
|
|
- };
|
|
|
+module.exports = SearchClient;
|
|
|
|
|
|
- lib.updatePage = function(id, path, body, creator, likeCount, bookmarkCount, updated, is_public) {
|
|
|
- };
|
|
|
+/*
|
|
|
|
|
|
lib.searchPageByKeyword = function(keyword) {
|
|
|
var queryBody = {
|
|
|
@@ -248,10 +299,4 @@ module.exports = function(crowi) {
|
|
|
|
|
|
};
|
|
|
|
|
|
- lib.searchPageByLikeCount = function() {
|
|
|
- };
|
|
|
-
|
|
|
- return lib;
|
|
|
-};
|
|
|
-
|
|
|
*/
|