Add endpoint for full-text search (#6)
This commit is contained in:
parent
273460b126
commit
e55720e3bb
@ -5,7 +5,7 @@ const path = require('path')
|
||||
|
||||
class IonicUnit extends Unit {
|
||||
static get services() {
|
||||
return [...super.services, 'configs', 'express', 'canon', 'utility']
|
||||
return [...super.services, 'configs', 'express', 'canon', 'utility', 'scaffold']
|
||||
}
|
||||
|
||||
constructor(...args) {
|
||||
@ -33,6 +33,16 @@ class IonicUnit extends Unit {
|
||||
},
|
||||
Express.static(this.directory),
|
||||
])
|
||||
|
||||
// Create the full-text search indices
|
||||
const pages = this.scaffold.collection('api_Page')
|
||||
await pages.createIndex({ Name: 'text' })
|
||||
|
||||
const nodes = this.scaffold.collection('api_Node')
|
||||
await nodes.createIndex({ 'Value.Value': 'text' })
|
||||
|
||||
const databases = this.scaffold.collection('api_db_Database')
|
||||
await databases.createIndex({ Name: 'text' })
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,57 @@ class Misc extends Controller {
|
||||
return res.api(token.token)
|
||||
}
|
||||
|
||||
async get_search(req, res, next) {
|
||||
if ( !req.query.query ) {
|
||||
return res.status(400)
|
||||
.message('Missing query.')
|
||||
.api()
|
||||
}
|
||||
|
||||
const query = String(req.query.query)
|
||||
|
||||
const Page = this.models.get('api:Page')
|
||||
const Node = this.models.get('api:Node')
|
||||
|
||||
const all_user_page_ids = (await req.user.get_accessible_pages()).map(x => x.UUID)
|
||||
const results = []
|
||||
|
||||
const matching_pages = await Page.find({
|
||||
UUID: { $in: all_user_page_ids },
|
||||
Active: true,
|
||||
$text: { $search: query },
|
||||
})
|
||||
|
||||
for ( const page of matching_pages ) {
|
||||
results.push({
|
||||
title: page.Name,
|
||||
type: 'page',
|
||||
id: page.UUID,
|
||||
})
|
||||
}
|
||||
|
||||
const matching_nodes = await Node.find({
|
||||
PageId: { $in: all_user_page_ids },
|
||||
'Value.Mode': 'norm',
|
||||
$text: { $search: query }
|
||||
})
|
||||
|
||||
for ( const node of matching_nodes ) {
|
||||
const page = await node.page
|
||||
results.push({
|
||||
title: node.Value.Value,
|
||||
type: 'node',
|
||||
id: node.UUID,
|
||||
associated: {
|
||||
title: page.Name,
|
||||
type: 'page',
|
||||
id: page.UUID,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return res.api({results})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Misc
|
||||
|
@ -31,7 +31,7 @@ class Node extends Model {
|
||||
// Static and instance methods can go here
|
||||
get page() {
|
||||
const Page = this.models.get('api:Page')
|
||||
return this.belongs_to_one(Page, "PageId", "_id")
|
||||
return this.belongs_to_one(Page, "PageId", "UUID")
|
||||
}
|
||||
|
||||
to_html() {
|
||||
|
@ -21,6 +21,36 @@ class User extends AuthUser {
|
||||
return Page.findOne({OrgUserId: this._id, ParentId: '0'})
|
||||
}
|
||||
|
||||
async get_accessible_pages() {
|
||||
const Page = this.models.get('api:Page')
|
||||
const user_page = await this.get_root_page()
|
||||
|
||||
const user_pages = await user_page.visible_flat_children(this)
|
||||
|
||||
let view_pages = await Page.find({ shared_users_view: this._id })
|
||||
for ( const page of view_pages ) {
|
||||
view_pages = [...view_pages, ...(await page.visible_flat_children(this))]
|
||||
}
|
||||
|
||||
let update_pages = await Page.find({ shared_users_update: this._id })
|
||||
for ( const page of update_pages ) {
|
||||
update_pages = [...update_pages, ...(await page.visible_flat_children(this))]
|
||||
}
|
||||
|
||||
let manage_pages = await Page.find({ shared_users_manage: this._id })
|
||||
for ( const page of manage_pages ) {
|
||||
manage_pages = [...manage_pages, ...(await page.visible_flat_children(this))]
|
||||
}
|
||||
|
||||
const all_pages = [...user_pages, ...view_pages, ...update_pages, ...manage_pages].filter(x => !x.virtual)
|
||||
const uniq_page_obj = {}
|
||||
for ( const page of all_pages ) {
|
||||
uniq_page_obj[page.UUID] = page
|
||||
}
|
||||
|
||||
return Object.values(uniq_page_obj)
|
||||
}
|
||||
|
||||
// Other members and methods here
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ const index = {
|
||||
|
||||
// Export the entire personal tree as HTML
|
||||
'/data/export/html': ['controller::Export.html_export'],
|
||||
|
||||
'/search': ['controller::api:v1:Misc.get_search'],
|
||||
},
|
||||
|
||||
post: {
|
||||
|
@ -25,6 +25,6 @@
|
||||
"flitter-orm": "^0.4.0",
|
||||
"flitter-upload": "^0.8.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"libflitter": "^0.54.0"
|
||||
"libflitter": "^0.54.1"
|
||||
}
|
||||
}
|
||||
|
@ -2443,10 +2443,10 @@ leven@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3"
|
||||
integrity sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=
|
||||
|
||||
libflitter@^0.54.0:
|
||||
version "0.54.0"
|
||||
resolved "https://registry.yarnpkg.com/libflitter/-/libflitter-0.54.0.tgz#5758fd0069de0ed75a80385c66809078b8210c36"
|
||||
integrity sha512-/pRgUD5dXdpEPxR6B3Do5BZQTGLrTYj3u0ZxYr7GViB4NysLePkR8Vg3gBzuNYUkEznzWxDR8VcmtuIiEowhFw==
|
||||
libflitter@^0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/libflitter/-/libflitter-0.54.1.tgz#e866677dd1fec1717876e1700b6d95bc2db51e0e"
|
||||
integrity sha512-vPFJenYWhePboGBhU5Dc6UkxxNOFzlxnfppjGpp3JSPDJ5b7M7wykLL1k5pi8RVTT859Js9CIqI1NoqH+cTdaw==
|
||||
dependencies:
|
||||
colors "^1.3.3"
|
||||
connect-mongodb-session "^2.2.0"
|
||||
|
Loading…
Reference in New Issue
Block a user