Refactor further search

- in the end, the error was due to not asking for the id of the author
back of the Post.. grrr.... why couldn't we get better error messages!!

- Co-authored-by: Moriz Wahl <moriz.wahl@gmx.de>
This commit is contained in:
mattwr18 2019-12-13 15:56:18 +01:00
parent 2f4125b5d1
commit 4cd43b68a4
5 changed files with 38 additions and 58 deletions

View File

@ -1,64 +1,56 @@
import uuid from 'uuid/v4'
const transformReturnType = record => { const transformReturnType = record => {
return { return {
id: uuid(), __typename: record.get('type'),
searchResults: { ...record.get('resource').properties,
__typename: record.get('type'),
...record.get('resource').properties,
},
} }
} }
export default { export default {
Query: { Query: {
findResources: async (_parent, args, context, _resolveInfo) => { findResources: async (_parent, args, context, _resolveInfo) => {
const query = args.query const { query, limit } = args
const filter = {} const filter = {}
const limit = args.limit const { id: thisUserId } = context.user
const { user } = context // const postQuery = query.replace(/\s/g, '~ ') + '~'
const thisUserId = user.id // const userQuery = query.replace(/\s/g, '~ ') + '~'
const postQuery = query.replace(/\s/g, '~ ') + '~'
const userQuery = query.replace(/\s/g, '~ ') + '~'
const postCypher = ` const postCypher = `
CALL db.index.fulltext.queryNodes('post_fulltext_search', $query) CALL db.index.fulltext.queryNodes('post_fulltext_search', $query)
YIELD node as resource, score YIELD node as resource, score
MATCH (resource)<-[:WROTE]-(user:User) MATCH (resource)<-[:WROTE]-(user:User)
WHERE score >= 0.2 WHERE score >= 0.5
AND NOT user.deleted = true AND NOT user.disabled = true AND NOT user.deleted = true AND NOT user.disabled = true
AND NOT resource.deleted = true AND NOT resource.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 in COALESCE($filter.author_not.id_in, [])
AND NOT (:User { id: $thisUserId })-[:BLOCKED]->(user) AND NOT (:User { id: $thisUserId })-[:BLOCKED]-(user)
RETURN resource, labels(resource)[0] AS type RETURN resource, labels(resource)[0] AS type
LIMIT $limit LIMIT $limit
` `
const session = context.driver.session() const session = context.driver.session()
const postResults = await session.run(postCypher, { const postResults = await session.run(postCypher, {
query: postQuery, query,
filter: filter, filter,
limit: limit, limit,
thisUserId: thisUserId, thisUserId,
}) })
session.close() session.close()
const userCypher = ` const userCypher = `
CALL db.index.fulltext.queryNodes('user_fulltext_search', $query) CALL db.index.fulltext.queryNodes('user_fulltext_search', $query)
YIELD node as resource, score YIELD node as resource, score
MATCH (resource) MATCH (resource)
WHERE score >= 0.2 WHERE score >= 0.5
AND NOT resource.deleted = true AND NOT resource.disabled = true AND NOT resource.deleted = true AND NOT resource.disabled = true
AND NOT (:User { id: $thisUserId })-[:BLOCKED]->(resource) AND NOT (:User { id: $thisUserId })-[:BLOCKED]-(resource)
RETURN resource, labels(resource)[0] AS type RETURN resource, labels(resource)[0] AS type
LIMIT $limit LIMIT $limit
` `
const userResults = await session.run(userCypher, { const userResults = await session.run(userCypher, {
query: userQuery, query,
filter: filter, filter,
limit: limit, limit,
thisUserId: thisUserId, thisUserId,
}) })
session.close() session.close()
const result = postResults.records.concat(userResults.records).map(transformReturnType) let result = [...postResults.records, ...userResults.records]
result = result.map(transformReturnType)
return result return result
}, },
}, },

View File

@ -1,9 +1,4 @@
type SearchResult { union SearchResult = Post | User
id: ID!
searchResults: ResourceResults
}
union ResourceResults = Post | User
type Query { type Query {
findResources(query: String!, limit: Int = 5): [SearchResult]! findResources(query: String!, limit: Int = 5): [SearchResult]!

View File

@ -150,8 +150,7 @@ export default {
query: value, query: value,
}, },
}) })
const searchResults = findResources.map(searchResult => searchResult.searchResults) this.searchResults = findResources
this.searchResults = searchResults
} catch (error) { } catch (error) {
this.searchResults = [] this.searchResults = []
} finally { } finally {

View File

@ -3,27 +3,25 @@ import gql from 'graphql-tag'
export const findResourcesQuery = gql` export const findResourcesQuery = gql`
query($query: String!) { query($query: String!) {
findResources(query: $query, limit: 5) { findResources(query: $query, limit: 5) {
id __typename
searchResults { ... on Post {
__typename id
... on Post { title
id slug
title commentsCount
slug shoutedCount
commentsCount createdAt
shoutedCount author {
createdAt
author {
name
}
}
... on User {
id id
name name
slug
avatar
} }
} }
... on User {
id
name
slug
avatar
}
} }
} }
` `

View File

@ -82,7 +82,7 @@
</template> </template>
<script> <script>
import { mapGetters, mapActions } from 'vuex' import { mapGetters } from 'vuex'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import SearchInput from '~/components/SearchInput/SearchInput.vue' import SearchInput from '~/components/SearchInput/SearchInput.vue'
import Modal from '~/components/Modal' import Modal from '~/components/Modal'
@ -126,10 +126,6 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions({
quickSearchClear: 'search/quickClear',
quickSearch: 'search/quickSearch',
}),
goToResource(item) { goToResource(item) {
this.$nextTick(() => { this.$nextTick(() => {
switch (item.__typename) { switch (item.__typename) {