Skip to content

Commit

Permalink
chore: improve get media for area query
Browse files Browse the repository at this point in the history
chore: climb/area/user profile media share the same type
  • Loading branch information
viet nguyen committed Apr 30, 2023
1 parent 9e9be63 commit db8c246
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 210 deletions.
2 changes: 1 addition & 1 deletion src/db/MediaTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export interface SimpleTag {
name: string
type: number
}
export interface UserMediaWithTags extends MediaObjectType {
export interface MediaWithTags extends MediaObjectType {
climbTags: SimpleTag[]
areaTags: SimpleTag[]
}
Expand Down
4 changes: 2 additions & 2 deletions src/graphql/media/queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MediaListByAuthorType, UserMediaWithTags, TagsLeaderboardType } from '../../db/MediaTypes.js'
import { MediaListByAuthorType, MediaWithTags, TagsLeaderboardType } from '../../db/MediaTypes.js'
import { DataSourcesType } from '../../types.js'

const MediaQueries = {
Expand All @@ -22,7 +22,7 @@ const MediaQueries = {
/**
* Return most recent tags
*/
getUserMedia: async (_, { userUuid, limit = 1000 }: { limit: number | undefined, userUuid: string }, { dataSources }): Promise<UserMediaWithTags[]> => {
getUserMedia: async (_, { userUuid, limit = 1000 }: { limit: number | undefined, userUuid: string }, { dataSources }): Promise<MediaWithTags[]> => {
const { media }: DataSourcesType = dataSources
return await media.getUserMedia(userUuid, limit)
},
Expand Down
4 changes: 2 additions & 2 deletions src/graphql/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ const resolvers = {
}),

media: async (node: any, args: any, { dataSources }) => {
const { areas }: { areas: AreaDataSource } = dataSources
return await areas.findMediaByAreaId(node.metadata.area_id, node.ancestors)
const { media }: { media: MediaDataSource } = dataSources
return await media.findMediaByAreaId(node.metadata.area_id, node.ancestors)
},

createdBy: (node: AreaType) => node?.createdBy?.toUUID().toString(),
Expand Down
198 changes: 1 addition & 197 deletions src/model/AreaDataSource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MongoDataSource } from 'apollo-datasource-mongodb'
import { Filter } from 'mongodb'
import muuid, { MUUID } from 'uuid-mongodb'
import muuid from 'uuid-mongodb'
import bboxPolygon from '@turf/bbox-polygon'

import { getAreaModel, getMediaModel, getMediaObjectModel } from '../db/index.js'
Expand All @@ -9,8 +9,6 @@ import { GQLFilter, AreaFilterParams, PathTokenParams, LeafStatusParams, Compari
import { getClimbModel } from '../db/ClimbSchema.js'
import { ClimbGQLQueryType } from '../db/ClimbTypes.js'
import { logger } from '../logger.js'
import { UserMediaWithTags } from '../db/MediaTypes.js'
import { joiningTagWithMediaObject } from './MediaDataSource.js'

export default class AreaDataSource extends MongoDataSource<AreaType> {
areaModel = getAreaModel()
Expand Down Expand Up @@ -124,200 +122,6 @@ export default class AreaDataSource extends MongoDataSource<AreaType> {
return rs
}

/**
* Find all climb tags and area tags for a given areaId
* @param areaId area ID to search
* @param ancestors this area ancestors
* @returns array of base tag
*/
async findMediaByAreaId (areaId: MUUID, ancestors: string): Promise<UserMediaWithTags[]> {
/**
* Find all area tags whose ancestors and children have 'areaId'
*/
const taggedAreas = await getMediaModel().aggregate<UserMediaWithTags>([
...joiningTagWithMediaObject,
{
$unset: ['_id', 'onModel', 'mediaType', 'destType', 'mediaUuid']
},
{
// SELECT *
// FROM media
// LEFT JOIN areas
// ON media.destinationId == areas.metadata.area_id
$lookup: {
from: 'areas', // other collection name
foreignField: 'metadata.area_id',
localField: 'destinationId',
as: 'taggedArea',
pipeline: [{
$match: {
$expr: {
$or: [
// { // Case 1: given a child area, inheret its ancestor's photos
// // - input: A,B,C <-- area I want to search for tags
// // - regex: A,B
// $regexMatch: {
// input: ancestors,
// regex: '$ancestors',
// options: 'i'
// }
// },
{ // Case 2: given a ancestor area, inherit descendant photos
// - input: A,B,C
// - regex: A,B <-- area I want to search for tags
$regexMatch: {
input: '$ancestors',
regex: ancestors,
options: 'i'
}
}
]
}
}
}]
}
},
{
$match: {
taggedArea: {
$ne: []
}
}
},
{
$unset: ['destinationId']
},
{
$set: {
taggedArea: {
$map: {
input: '$taggedArea',
in: {
id: '$$this.metadata.area_id',
name: '$$this.area_name',
type: 1
}
}
}
}
},
{
$unwind: '$taggedArea'
},
{
$group: {
_id: {
mediaUrl: '$mediaUrl',
width: '$width',
height: '$height',
birthTime: '$birthTime',
mtime: '$mtime',
format: '$format',
size: '$size'
},
taggedArea: { $push: '$taggedArea' }
}
},
{
$addFields: {
'_id.areaTags': '$taggedArea'
}
},
{ $replaceRoot: { newRoot: '$_id' } }
])

/**
* Find all climb tags whose ancestors have areaId
*/
const taggeClimbs = await getMediaModel()
.aggregate<UserMediaWithTags>([
...joiningTagWithMediaObject,
{
$unset: ['_id', 'onModel', 'mediaType', 'destType', 'mediaUuid']
},
{
// SELECT *
// FROM media
// LEFT OUTER climbs
// ON climbs._id == media.destinationId
$lookup: {
from: 'climbs', // other collection name
foreignField: '_id', // climb._id
localField: 'destinationId',
as: 'taggedClimbs',
pipeline: [{
$lookup: { // also allow ancestor areas to inherent climb photo
from: 'areas', // other collection name
foreignField: 'metadata.area_id',
localField: 'metadata.areaRef', // climb.metadata.areaRef
as: 'area'
}
},
{
$match: {
'area.ancestors': { $regex: areaId.toUUID().toString() }
}
}
]
}
},
{
$match: {
taggedClimbs: {
$ne: []
}
}
},
{
$unset: ['destinationId']
},
{
$set: {
taggedClimbs: {
$map: {
input: '$taggedClimbs',
in: {
id: '$$this._id',
name: '$$this.name',
type: 0
}
}
}
}
},
{
$unwind: '$taggedClimbs'
},
{
$group: {
_id: {
mediaUrl: '$mediaUrl',
width: '$width',
height: '$height',
birthTime: '$birthTime',
mtime: '$mtime',
format: '$format',
size: '$size'
},
climbTags: { $push: '$taggedClimbs' }
}
},
{
$addFields: {
'_id.climbTags': '$climbTags'
}
},
{ $replaceRoot: { newRoot: '$_id' } }
])

// combine 2 result sets
if (taggeClimbs != null) {
return taggeClimbs.concat(taggedAreas)
} else {
return taggedAreas
}
}

/**
* Find a climb by uuid. Also return the parent area object (crag or boulder).
*
Expand Down
Loading

0 comments on commit db8c246

Please sign in to comment.