From ebc5cf392d92acf3a9e22c8967d02ea2cf6fd7fb Mon Sep 17 00:00:00 2001 From: mattwr18 Date: Fri, 13 Dec 2019 12:30:00 +0100 Subject: [PATCH] Fix search by adding result id - Apollo cache requires an id to commit to their store - add id to each query result - refactor out the store - still can use a lot of refactoring --- backend/src/schema/resolvers/searches.js | 46 ++- backend/src/schema/types/type/Search.gql | 7 +- webapp/components/SearchInput/SearchInput.vue | 283 ++++++++++-------- webapp/graphql/Search.js | 29 ++ webapp/layouts/default.vue | 12 +- webapp/store/search.js | 92 ------ 6 files changed, 208 insertions(+), 261 deletions(-) create mode 100644 webapp/graphql/Search.js delete mode 100644 webapp/store/search.js diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.js index 61b0eb63f..cbf301e24 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.js @@ -1,15 +1,15 @@ -export default { - SearchResult: { - __resolveType(obj, context, info) { - if (obj.encryptedPassword) { - return 'User' - } - if (obj.content) { - return 'Post' - } - return null +import uuid from 'uuid/v4' + +const transformReturnType = record => { + return { + id: uuid(), + searchResults: { + __typename: record.get('type'), + ...record.get('resource').properties, }, - }, + } +} +export default { Query: { findResources: async (_parent, args, context, _resolveInfo) => { const query = args.query @@ -21,14 +21,14 @@ export default { const userQuery = query.replace(/\s/g, '~ ') + '~' const postCypher = ` CALL db.index.fulltext.queryNodes('post_fulltext_search', $query) - YIELD node as post, score - MATCH (post)<-[:WROTE]-(user:User) + YIELD node as resource, score + MATCH (resource)<-[:WROTE]-(user:User) WHERE score >= 0.2 AND NOT user.deleted = true AND NOT user.disabled = true - AND NOT post.deleted = true AND NOT post.disabled = true + AND NOT resource.deleted = true AND NOT resource.disabled = true AND NOT user.id in COALESCE($filter.author_not.id_in, []) AND NOT (:User { id: $thisUserId })-[:BLOCKED]->(user) - RETURN post + RETURN resource, labels(resource)[0] AS type LIMIT $limit ` const session = context.driver.session() @@ -41,12 +41,12 @@ export default { session.close() const userCypher = ` CALL db.index.fulltext.queryNodes('user_fulltext_search', $query) - YIELD node as user, score - MATCH (user) + YIELD node as resource, score + MATCH (resource) WHERE score >= 0.2 - AND NOT user.deleted = true AND NOT user.disabled = true - AND NOT (:User { id: $thisUserId })-[:BLOCKED]->(user) - RETURN user + AND NOT resource.deleted = true AND NOT resource.disabled = true + AND NOT (:User { id: $thisUserId })-[:BLOCKED]->(resource) + RETURN resource, labels(resource)[0] AS type LIMIT $limit ` const userResults = await session.run(userCypher, { @@ -57,10 +57,8 @@ export default { }) session.close() - const result = [] - postResults.records - .concat(userResults.records) - .forEach(record => result.push(record._fields[0].properties)) + const result = postResults.records.concat(userResults.records).map(transformReturnType) + return result }, }, diff --git a/backend/src/schema/types/type/Search.gql b/backend/src/schema/types/type/Search.gql index 2c22fa61f..eab7f87ba 100644 --- a/backend/src/schema/types/type/Search.gql +++ b/backend/src/schema/types/type/Search.gql @@ -1,4 +1,9 @@ -union SearchResult = Post | User +type SearchResult { + id: ID! + searchResults: ResourceResults +} + +union ResourceResults = Post | User type Query { findResources(query: String!, limit: Int = 5): [SearchResult]! diff --git a/webapp/components/SearchInput/SearchInput.vue b/webapp/components/SearchInput/SearchInput.vue index a7cc6659c..54536111e 100644 --- a/webapp/components/SearchInput/SearchInput.vue +++ b/webapp/components/SearchInput/SearchInput.vue @@ -23,7 +23,7 @@ :no-options-available="emptyText" :icon-right="isActive ? 'close' : null" :filter="item => item" - :options="results" + :options="searchResults" :auto-reset-search="!searchValue" :placeholder="$t('search.placeholder')" :loading="pending" @@ -45,7 +45,7 @@ - +
@@ -93,6 +93,8 @@ diff --git a/webapp/graphql/Search.js b/webapp/graphql/Search.js new file mode 100644 index 000000000..f71c848c7 --- /dev/null +++ b/webapp/graphql/Search.js @@ -0,0 +1,29 @@ +import gql from 'graphql-tag' + +export const findResourcesQuery = gql` + query($query: String!) { + findResources(query: $query, limit: 5) { + id + searchResults { + __typename + ... on Post { + id + title + slug + commentsCount + shoutedCount + createdAt + author { + name + } + } + ... on User { + id + name + slug + avatar + } + } + } + } +` diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index 55fde8296..852e19699 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -21,15 +21,7 @@ :class="{ 'hide-mobile-menu': !toggleMobileMenu }" > { - return { - quickResults: [], - quickPending: false, - quickValue: '', - } -} - -export const mutations = { - SET_QUICK_RESULTS(state, results) { - state.quickResults = results || [] - state.quickPending = false - }, - SET_QUICK_PENDING(state, pending) { - state.quickPending = pending - }, - SET_QUICK_VALUE(state, value) { - state.quickValue = value - }, -} - -export const getters = { - quickResults(state) { - return state.quickResults - }, - quickPending(state) { - return state.quickPending - }, - quickValue(state) { - return state.quickValue - }, -} - -export const actions = { - async quickSearch({ commit, getters }, { value }) { - value = isString(value) ? value.trim() : '' - const lastVal = getters.quickValue - if (value.length < 3 || lastVal.toLowerCase() === value.toLowerCase()) { - return - } - commit('SET_QUICK_VALUE', value) - commit('SET_QUICK_PENDING', true) - await this.app.apolloProvider.defaultClient - .query({ - query: gql` - query findResources($query: String!) { - findResources(query: $query, limit: 5) { - __typename - ... on Post { - id - title - slug - commentsCount - shoutedCount - createdAt - author { - name - } - } - ... on User { - id - name - slug - avatar - } - } - } - `, - variables: { - query: value, - }, - }) - .then(res => { - commit('SET_QUICK_RESULTS', res.data.findResources || []) - }) - .catch(() => { - commit('SET_QUICK_RESULTS', []) - }) - .finally(() => { - commit('SET_QUICK_PENDING', false) - }) - return getters.quickResults - }, - async quickClear({ commit }) { - commit('SET_QUICK_PENDING', false) - commit('SET_QUICK_RESULTS', []) - commit('SET_QUICK_VALUE', '') - }, -}