Initial commit
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
const debug = require('debug')('termPortal:models/search-engine')
|
||||
const { Client } = require('@opensearch-project/opensearch')
|
||||
|
||||
const ENTRY_INDEX = 'entry'
|
||||
const CONSULTANCY_ENTRY_INDEX = 'consultancy_entry'
|
||||
const client = new Client({ node: 'http://opensearch:9200' })
|
||||
|
||||
exports.initEntryIndex = async () => {
|
||||
const { statusCode } = await client.indices.exists({ index: ENTRY_INDEX })
|
||||
|
||||
const doesIndexExist = statusCode === 200
|
||||
|
||||
if (doesIndexExist) {
|
||||
debug('Entry search index already exists.')
|
||||
return
|
||||
}
|
||||
|
||||
await client.indices.create({
|
||||
index: ENTRY_INDEX,
|
||||
body: {
|
||||
settings: {
|
||||
number_of_replicas: 0
|
||||
},
|
||||
mappings: {
|
||||
dynamic: 'strict',
|
||||
properties: {
|
||||
id: { type: 'keyword', index: false, doc_values: false },
|
||||
isValid: { type: 'boolean', doc_values: false },
|
||||
isPublished: { type: 'boolean', doc_values: false },
|
||||
isTerminologyReviewed: { type: 'boolean', doc_values: false },
|
||||
isLanguageReviewed: { type: 'boolean', doc_values: false },
|
||||
status: { type: 'keyword', doc_values: false },
|
||||
term: {
|
||||
type: 'text',
|
||||
doc_values: false,
|
||||
fields: {
|
||||
keyword: { type: 'keyword', doc_values: false },
|
||||
sort: {
|
||||
type: 'icu_collation_keyword',
|
||||
index: false,
|
||||
language: 'sl',
|
||||
country: 'SI'
|
||||
}
|
||||
}
|
||||
},
|
||||
homonymSort: { type: 'keyword', index: false },
|
||||
label: { type: 'text', doc_values: false },
|
||||
definition: { type: 'text', doc_values: false },
|
||||
synonyms: { type: 'text', doc_values: false },
|
||||
other: { type: 'text', doc_values: false },
|
||||
timeMostRecentComment: { type: 'date' },
|
||||
domainLabels: { type: 'text', doc_values: false },
|
||||
links: { type: 'text', doc_values: false },
|
||||
foreignEntries: {
|
||||
type: 'nested',
|
||||
properties: {
|
||||
lang: {
|
||||
properties: {
|
||||
id: { type: 'keyword' },
|
||||
code: { type: 'keyword', index: false, doc_values: false },
|
||||
nameSl: { type: 'keyword', index: false, doc_values: false },
|
||||
nameEn: { type: 'keyword', index: false, doc_values: false }
|
||||
}
|
||||
},
|
||||
terms: {
|
||||
type: 'text',
|
||||
doc_values: false,
|
||||
fields: {
|
||||
keyword: { type: 'keyword', doc_values: false }
|
||||
}
|
||||
},
|
||||
definition: { type: 'text', doc_values: false },
|
||||
synonyms: { type: 'text', doc_values: false }
|
||||
}
|
||||
},
|
||||
primaryDomain: {
|
||||
properties: {
|
||||
id: { type: 'keyword' },
|
||||
nameSl: { type: 'keyword', index: false, doc_values: false },
|
||||
nameEn: { type: 'keyword', index: false, doc_values: false }
|
||||
}
|
||||
},
|
||||
dictionary: {
|
||||
properties: {
|
||||
id: { type: 'keyword' },
|
||||
nameSl: { type: 'keyword', index: false, doc_values: false },
|
||||
nameSlShort: { type: 'keyword', index: false, doc_values: false },
|
||||
nameEn: { type: 'keyword', index: false, doc_values: false },
|
||||
status: { type: 'keyword', doc_values: false }
|
||||
}
|
||||
},
|
||||
source: {
|
||||
properties: {
|
||||
code: { type: 'keyword' },
|
||||
name: { type: 'keyword', index: false, doc_values: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
debug('Entry search index created.')
|
||||
}
|
||||
|
||||
exports.initConsultancyEntryIndex = async () => {
|
||||
const { statusCode } = await client.indices.exists({
|
||||
index: CONSULTANCY_ENTRY_INDEX
|
||||
})
|
||||
|
||||
const doesIndexExist = statusCode === 200
|
||||
|
||||
if (doesIndexExist) {
|
||||
debug('Consultancy entry search index already exists.')
|
||||
return
|
||||
}
|
||||
|
||||
await client.indices.create({
|
||||
index: CONSULTANCY_ENTRY_INDEX,
|
||||
body: {
|
||||
settings: {
|
||||
number_of_replicas: 0
|
||||
},
|
||||
mappings: {
|
||||
dynamic: 'strict',
|
||||
properties: {
|
||||
id: { type: 'keyword', index: false, doc_values: false },
|
||||
timeCreated: { type: 'date', index: false },
|
||||
status: { type: 'keyword', doc_values: false },
|
||||
description: { type: 'text', index: false, doc_values: false },
|
||||
title: { type: 'text', doc_values: false },
|
||||
question: { type: 'text', doc_values: false },
|
||||
answer: { type: 'text', doc_values: false },
|
||||
answerAuthors: { type: 'keyword', index: false, doc_values: false },
|
||||
primaryDomain: {
|
||||
properties: {
|
||||
id: { type: 'keyword', doc_values: false },
|
||||
nameSl: { type: 'keyword', index: false, doc_values: false },
|
||||
nameEn: { type: 'keyword', index: false, doc_values: false }
|
||||
}
|
||||
},
|
||||
assignedConsultants: {
|
||||
properties: {
|
||||
id: { type: 'keyword', doc_values: false },
|
||||
firstName: { type: 'keyword', index: false, doc_values: false },
|
||||
lastName: { type: 'keyword', index: false, doc_values: false },
|
||||
isModerator: { type: 'boolean', index: false, doc_values: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
debug('Consultancy entry search index created.')
|
||||
}
|
||||
|
||||
exports.waitForConnection = () => {
|
||||
return new Promise(resolve => {
|
||||
async function testConnection() {
|
||||
try {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Verifying connection to search engine server')
|
||||
await client.ping()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Connection to search engine server verified')
|
||||
resolve()
|
||||
} catch {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('Could not connect to search engine server')
|
||||
setTimeout(testConnection, 1000)
|
||||
}
|
||||
}
|
||||
testConnection()
|
||||
})
|
||||
}
|
||||
|
||||
exports.searchEngineClient = client
|
||||
|
||||
exports.ENTRY_INDEX = ENTRY_INDEX
|
||||
|
||||
exports.CONSULTANCY_ENTRY_INDEX = CONSULTANCY_ENTRY_INDEX
|
||||
|
||||
// A wrapper, to simplify querying the entry index.
|
||||
exports.searchEntryIndex = async query => {
|
||||
const hits = await client.search({
|
||||
index: ENTRY_INDEX,
|
||||
filter_path: 'hits,aggregations',
|
||||
body: query
|
||||
})
|
||||
|
||||
return hits
|
||||
}
|
||||
|
||||
// A wrapper, to simplify querying the consultancy entry index.
|
||||
exports.searchConsultancyEntryIndex = async query => {
|
||||
const hits = await client.search({
|
||||
index: CONSULTANCY_ENTRY_INDEX,
|
||||
filter_path: 'hits',
|
||||
body: query
|
||||
})
|
||||
|
||||
return hits
|
||||
}
|
||||
|
||||
exports.deleteEntryFromIndex = async (entryId, shouldWait) => {
|
||||
await client.delete({
|
||||
index: ENTRY_INDEX,
|
||||
id: entryId,
|
||||
refresh: shouldWait ? 'wait_for' : false
|
||||
})
|
||||
}
|
||||
|
||||
exports.deleteConsultancyEntryFromIndex = async (entryId, shouldWait) => {
|
||||
await client.delete({
|
||||
index: CONSULTANCY_ENTRY_INDEX,
|
||||
id: entryId,
|
||||
refresh: shouldWait ? 'wait_for' : false
|
||||
})
|
||||
}
|
||||
|
||||
exports.deleteDictionaryEntriesFromIndex = async dictionaryId => {
|
||||
await client.deleteByQuery({
|
||||
index: ENTRY_INDEX,
|
||||
body: {
|
||||
query: {
|
||||
term: {
|
||||
'dictionary.id': {
|
||||
value: dictionaryId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
exports.deleteConsultancyEntriesFromIndex = async () => {
|
||||
await client.deleteByQuery({
|
||||
index: CONSULTANCY_ENTRY_INDEX,
|
||||
body: {
|
||||
query: {
|
||||
match_all: {}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user