sepia-search-motore-di-rice.../server/lib/elastic-search-channels.ts

214 lines
4.6 KiB
TypeScript
Raw Normal View History

2020-02-19 15:39:35 +01:00
import { CONFIG } from '../initializers/constants'
import { VideoChannel } from '@shared/models'
import { buildIndex, buildSort, elasticSearch, extractQueryResult, indexDocuments } from '../helpers/elastic-search'
import { logger } from '../helpers/logger'
import { DBChannel, IndexableChannel } from '../types/channel.model'
import { ChannelsSearchQuery } from '../types/channel-search.model'
import { buildAvatarMapping, formatAvatarForAPI, formatAvatarForDB } from './elastic-search-avatar'
function initChannelsIndex () {
return buildIndex(CONFIG.ELASTIC_SEARCH.INDEXES.CHANNELS, buildChannelsMapping())
}
async function indexChannels (channels: IndexableChannel[], replace = false) {
return indexDocuments({
objects: channels,
formatter: c => formatChannelForDB(c),
replace,
index: CONFIG.ELASTIC_SEARCH.INDEXES.CHANNELS
})
}
function refreshChannelsIndex () {
return elasticSearch.indices.refresh({ index: CONFIG.ELASTIC_SEARCH.INDEXES.CHANNELS })
}
async function queryChannels (search: ChannelsSearchQuery) {
const bool: any = {}
if (search.search) {
Object.assign(bool, {
must: [
{
multi_match: {
query: search.search,
fields: [ 'name', 'displayName', 'description' ],
fuzziness: 'AUTO'
}
}
]
})
}
const body = {
from: search.start,
size: search.count,
sort: buildSort(search.sort),
query: { bool }
}
logger.debug('Will query Elastic Search for channels.', { body })
const res = await elasticSearch.search({
index: CONFIG.ELASTIC_SEARCH.INDEXES.CHANNELS,
body
})
return extractQueryResult(res)
}
export {
initChannelsIndex,
indexChannels,
refreshChannelsIndex,
formatChannelForAPI,
queryChannels
}
// ############################################################################
function formatChannelForDB (c: IndexableChannel): DBChannel {
return {
id: c.id,
url: c.url,
name: c.name,
host: c.host,
avatar: formatAvatarForDB(c),
displayName: c.displayName,
indexedAt: new Date(),
followingCount: c.followingCount,
followersCount: c.followersCount,
createdAt: c.createdAt,
updatedAt: c.updatedAt,
description: c.description,
support: c.support,
ownerAccount: {
id: c.ownerAccount.id,
url: c.ownerAccount.url,
displayName: c.ownerAccount.displayName,
description: c.ownerAccount.description,
name: c.ownerAccount.name,
host: c.ownerAccount.host,
followingCount: c.ownerAccount.followingCount,
followersCount: c.ownerAccount.followersCount,
createdAt: c.ownerAccount.createdAt,
updatedAt: c.ownerAccount.updatedAt,
avatar: formatAvatarForDB(c.ownerAccount)
}
}
}
function formatChannelForAPI (c: DBChannel, fromHost?: string): VideoChannel {
return {
id: c.id,
url: c.url,
name: c.name,
host: c.host,
followingCount: c.followingCount,
followersCount: c.followersCount,
createdAt: c.createdAt,
updatedAt: c.updatedAt,
avatar: formatAvatarForAPI(c),
displayName: c.displayName,
description: c.description,
support: c.support,
isLocal: fromHost === c.host,
ownerAccount: {
id: c.ownerAccount.id,
url: c.ownerAccount.url,
displayName: c.ownerAccount.displayName,
description: c.ownerAccount.description,
name: c.ownerAccount.name,
host: c.ownerAccount.host,
followingCount: c.ownerAccount.followingCount,
followersCount: c.ownerAccount.followersCount,
createdAt: c.ownerAccount.createdAt,
updatedAt: c.ownerAccount.updatedAt,
avatar: formatAvatarForAPI(c.ownerAccount)
}
}
}
function buildChannelOrAccountCommonMapping () {
return {
id: {
type: 'long'
},
url: {
type: 'keyword'
},
name: {
type: 'text',
fields: {
raw: {
type: 'keyword'
}
}
},
host: {
type: 'keyword'
},
displayName: {
type: 'text'
},
avatar: {
properties: buildAvatarMapping()
},
followingCount: {
type: 'long'
},
followersCount: {
type: 'long'
},
createdAt: {
type: 'date',
format: 'date_optional_time'
},
updatedAt: {
type: 'date',
format: 'date_optional_time'
},
description: {
type: 'text'
}
}
}
function buildChannelsMapping () {
const base = buildChannelOrAccountCommonMapping()
Object.assign(base, {
support: {
type: 'keyword'
},
ownerAccount: {
properties: buildChannelOrAccountCommonMapping()
}
})
return base
}