From e236838523a7dc991f8e301b3580734c4e611933 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Fri, 7 Feb 2020 09:36:00 +0100 Subject: [PATCH 01/10] migration added for index for fulltext tag search --- .../20200207080200-fulltext_index_for_tags.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js diff --git a/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js b/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js new file mode 100644 index 000000000..0a92c90c3 --- /dev/null +++ b/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js @@ -0,0 +1,49 @@ +import { getDriver } from '../../db/neo4j' + +export const description = + 'This migration adds a fulltext index for the tags in order to search for Hasthags.' + +export async function up(next) { + const driver = getDriver() + const session = driver.session() + const transaction = session.beginTransaction() + + try { + await transaction.run(` + CALL db.index.fulltext.createNodeIndex("tag_fulltext_search",["Tag"],["id"]) + `) + await transaction.commit() + next() + } catch (error) { + // eslint-disable-next-line no-console + console.log(error) + await transaction.rollback() + // eslint-disable-next-line no-console + console.log('rolled back') + } finally { + session.close() + } +} + +export async function down(next) { + const driver = getDriver() + const session = driver.session() + const transaction = session.beginTransaction() + + try { + // Implement your migration here. + await transaction.run(` + CALL db.index.fulltext.drop("tag_fulltext_search") + `) + await transaction.commit() + next() + } catch (error) { + // eslint-disable-next-line no-console + console.log(error) + await transaction.rollback() + // eslint-disable-next-line no-console + console.log('rolled back') + } finally { + session.close() + } +} From 16ad565ec8c3ff83d6b363861ada7ea0a29d3ce9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 11 Feb 2020 09:27:28 +0100 Subject: [PATCH 02/10] partially working, index page does not update when route is changed --- .../generic/SearchTag/SearchTag.vue | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 webapp/components/generic/SearchTag/SearchTag.vue diff --git a/webapp/components/generic/SearchTag/SearchTag.vue b/webapp/components/generic/SearchTag/SearchTag.vue new file mode 100644 index 000000000..d8cfc0b31 --- /dev/null +++ b/webapp/components/generic/SearchTag/SearchTag.vue @@ -0,0 +1,23 @@ + + + From 014be6e7f885a84668739a7697a53de5797fd61c Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 11 Feb 2020 09:27:41 +0100 Subject: [PATCH 03/10] partially working, index page does not update when route is changed --- backend/src/schema/resolvers/searches.js | 27 +++++++++++++-- backend/src/schema/types/type/Search.gql | 2 +- webapp/components/Hashtag/Hashtag.vue | 2 +- .../generic/SearchTag/SearchTag.vue | 24 ++++++------- .../SearchableInput/SearchableInput.vue | 34 ++++++++++++++++--- webapp/graphql/Search.js | 3 ++ webapp/locales/de.json | 29 ++++++++++++++++ webapp/locales/en.json | 10 ++++++ 8 files changed, 110 insertions(+), 21 deletions(-) diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.js index 5c1e43952..d4a2bf02a 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.js @@ -43,6 +43,16 @@ export default { ` const myQuery = queryString(query) + const tagCypher = ` + CALL db.index.fulltext.queryNodes('tag_fulltext_search', $query) + YIELD node as resource, score + MATCH (resource) + WHERE score >= 0.5 + AND NOT (resource.deleted = true OR resource.disabled = true) + RETURN resource {.*, __typename: labels(resource)[0]} + LIMIT $limit + ` + const session = context.driver.session() const searchResultPromise = session.readTransaction(async transaction => { const postTransactionResponse = transaction.run(postCypher, { @@ -55,14 +65,25 @@ export default { limit, thisUserId, }) - return Promise.all([postTransactionResponse, userTransactionResponse]) + const tagTransactionResponse = transaction.run(tagCypher, { + query: myQuery, + limit, + }) + return Promise.all([ + postTransactionResponse, + userTransactionResponse, + tagTransactionResponse, + ]) }) try { - const [postResults, userResults] = await searchResultPromise + const [postResults, userResults, tagResults] = await searchResultPromise log(postResults) log(userResults) - return [...postResults.records, ...userResults.records].map(r => r.get('resource')) + log(tagResults) + return [...postResults.records, ...userResults.records, ...tagResults.records].map(r => + r.get('resource'), + ) } finally { session.close() } diff --git a/backend/src/schema/types/type/Search.gql b/backend/src/schema/types/type/Search.gql index 2c22fa61f..1ce38001d 100644 --- a/backend/src/schema/types/type/Search.gql +++ b/backend/src/schema/types/type/Search.gql @@ -1,4 +1,4 @@ -union SearchResult = Post | User +union SearchResult = Post | User | Tag type Query { findResources(query: String!, limit: Int = 5): [SearchResult]! diff --git a/webapp/components/Hashtag/Hashtag.vue b/webapp/components/Hashtag/Hashtag.vue index 35762c81c..44e5319f0 100644 --- a/webapp/components/Hashtag/Hashtag.vue +++ b/webapp/components/Hashtag/Hashtag.vue @@ -1,5 +1,5 @@ diff --git a/webapp/components/generic/SearchTag/SearchTag.vue b/webapp/components/generic/SearchTag/SearchTag.vue index d8cfc0b31..a94431eea 100644 --- a/webapp/components/generic/SearchTag/SearchTag.vue +++ b/webapp/components/generic/SearchTag/SearchTag.vue @@ -6,18 +6,18 @@ diff --git a/webapp/components/generic/SearchableInput/SearchableInput.vue b/webapp/components/generic/SearchableInput/SearchableInput.vue index 3260ff082..654deaad4 100644 --- a/webapp/components/generic/SearchableInput/SearchableInput.vue +++ b/webapp/components/generic/SearchableInput/SearchableInput.vue @@ -35,6 +35,12 @@ >

+

+ +

@@ -45,6 +51,7 @@ import { isEmpty } from 'lodash' import SearchHeading from '~/components/generic/SearchHeading/SearchHeading.vue' import SearchPost from '~/components/generic/SearchPost/SearchPost.vue' +import HcHashtag from '~/components/Hashtag/Hashtag.vue' import UserTeaser from '~/components/UserTeaser/UserTeaser.vue' export default { @@ -52,6 +59,7 @@ export default { components: { SearchHeading, SearchPost, + HcHashtag, UserTeaser, }, props: { @@ -77,6 +85,16 @@ export default { return !isEmpty(this.previousSearchTerm) }, }, + watch: { + $route(to, from) { + console.log('to', to) + console.log('from', from) + // console.log(this.finalFilters) + if (to.query.hashtag) { + this.hashtag = to.query.hashtag + } + }, + }, methods: { isFirstOfType(option) { return ( @@ -138,12 +156,20 @@ export default { isPost(item) { return item.__typename === 'Post' }, + isTag(item) { + return item.__typename === 'Tag' + }, goToResource(item) { this.$nextTick(() => { - this.$router.push({ - name: this.isPost(item) ? 'post-id-slug' : 'profile-id-slug', - params: { id: item.id, slug: item.slug }, - }) + if (!this.isTag(item)) { + this.$router.push({ + name: this.isPost(item) ? 'post-id-slug' : 'profile-id-slug', + params: { id: item.id, slug: item.slug }, + }) + } else { + console.log('HIT¡') + this.$router.push('?hashtag=' + item.id) + } }) }, }, diff --git a/webapp/graphql/Search.js b/webapp/graphql/Search.js index 9b142b429..ab34b58b6 100644 --- a/webapp/graphql/Search.js +++ b/webapp/graphql/Search.js @@ -19,6 +19,9 @@ export const findResourcesQuery = gql` ... on User { ...user } + ... on Tag { + id + } } } ` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 524ee58fa..8f38c2352 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -558,6 +558,35 @@ "message": "Bist Du sicher, dass Du den Kommentar von „{name}“ melden möchtest?", "title": "Kommentar melden", "type": "Kommentar" + "content": { + "unavailable-placeholder": "… dieser Kommentar ist nicht mehr verfügbar" + }, + "menu": { + "edit": "Kommentar bearbeiten", + "delete": "Kommentar löschen" + }, + "show": { + "more": "mehr anzeigen", + "less": "weniger anzeigen" + }, + "edited": "bearbeitet" + }, + "followButton": { + "follow": "Folgen", + "following": "Folge Ich" + }, + "shoutButton": { + "shouted": "empfohlen" + }, + "search": { + "placeholder": "Suchen", + "hint": "Wonach suchst Du?", + "failed": "Nichts gefunden", + "heading": { + "Post": "Beiträge", + "User": "Benutzer", + "Tag": "Hashtags" + } }, "contribution": { "error": "Du hast den Beitrag bereits gemeldet!", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index e6b8def5a..642d0c228 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -549,6 +549,16 @@ "message": "Do you really want to release the user \"{name}\"?", "title": "Release User", "type": "User" + "empty": "Sorry, you don't have any notifications at the moment." + }, + "search": { + "placeholder": "Search", + "hint": "What are you searching for?", + "failed": "Nothing found", + "heading": { + "Post": "Posts", + "User": "Users", + "Tag": "Hashtags" } }, "report": { From 07fbe92fa81ab3828904545d9d58cd67e02238d3 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 19 Mar 2020 13:26:08 +0100 Subject: [PATCH 04/10] fixed locales after mistakes in rebase --- webapp/locales/de.json | 30 +----------------------------- webapp/locales/en.json | 11 +---------- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 8f38c2352..a2ab2246f 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -558,35 +558,6 @@ "message": "Bist Du sicher, dass Du den Kommentar von „{name}“ melden möchtest?", "title": "Kommentar melden", "type": "Kommentar" - "content": { - "unavailable-placeholder": "… dieser Kommentar ist nicht mehr verfügbar" - }, - "menu": { - "edit": "Kommentar bearbeiten", - "delete": "Kommentar löschen" - }, - "show": { - "more": "mehr anzeigen", - "less": "weniger anzeigen" - }, - "edited": "bearbeitet" - }, - "followButton": { - "follow": "Folgen", - "following": "Folge Ich" - }, - "shoutButton": { - "shouted": "empfohlen" - }, - "search": { - "placeholder": "Suchen", - "hint": "Wonach suchst Du?", - "failed": "Nichts gefunden", - "heading": { - "Post": "Beiträge", - "User": "Benutzer", - "Tag": "Hashtags" - } }, "contribution": { "error": "Du hast den Beitrag bereits gemeldet!", @@ -628,6 +599,7 @@ "failed": "Nichts gefunden", "heading": { "Post": "Beiträge", + "Tag": "Hashtags", "User": "Benutzer" }, "hint": "Wonach suchst Du?", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 642d0c228..eb19dfbe7 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -549,16 +549,6 @@ "message": "Do you really want to release the user \"{name}\"?", "title": "Release User", "type": "User" - "empty": "Sorry, you don't have any notifications at the moment." - }, - "search": { - "placeholder": "Search", - "hint": "What are you searching for?", - "failed": "Nothing found", - "heading": { - "Post": "Posts", - "User": "Users", - "Tag": "Hashtags" } }, "report": { @@ -609,6 +599,7 @@ "failed": "Nothing found", "heading": { "Post": "Posts", + "Tag": "Hashtags", "User": "Users" }, "hint": "What are you searching for?", From 1c43d5fe6f44c7b11168af8bd765b8d785a6641a Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 19 Mar 2020 14:19:13 +0100 Subject: [PATCH 05/10] Search for Hashtags works due watching route in pages/index.vue --- backend/src/db/migrate/template.js | 1 + .../20200207080200-fulltext_index_for_tags.js | 2 + backend/src/schema/resolvers/searches.js | 6 +- .../generic/SearchTag/SearchTag.vue | 23 -- .../SearchableInput/SearchableInput.vue | 11 - webapp/pages/index.vue | 306 +++++++++--------- 6 files changed, 162 insertions(+), 187 deletions(-) delete mode 100644 webapp/components/generic/SearchTag/SearchTag.vue diff --git a/backend/src/db/migrate/template.js b/backend/src/db/migrate/template.js index 9adb0786d..72bfc9b1b 100644 --- a/backend/src/db/migrate/template.js +++ b/backend/src/db/migrate/template.js @@ -40,6 +40,7 @@ export async function down(next) { await transaction.rollback() // eslint-disable-next-line no-console console.log('rolled back') + throw new Error(error) } finally { session.close() } diff --git a/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js b/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js index 0a92c90c3..5064a8b17 100644 --- a/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js +++ b/backend/src/db/migrations/20200207080200-fulltext_index_for_tags.js @@ -20,6 +20,7 @@ export async function up(next) { await transaction.rollback() // eslint-disable-next-line no-console console.log('rolled back') + throw new Error(error) } finally { session.close() } @@ -43,6 +44,7 @@ export async function down(next) { await transaction.rollback() // eslint-disable-next-line no-console console.log('rolled back') + throw new Error(error) } finally { session.close() } diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.js index d4a2bf02a..3471c783b 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.js @@ -41,18 +41,18 @@ export default { RETURN resource {.*, __typename: labels(resource)[0]} LIMIT $limit ` - const myQuery = queryString(query) - const tagCypher = ` CALL db.index.fulltext.queryNodes('tag_fulltext_search', $query) YIELD node as resource, score MATCH (resource) - WHERE score >= 0.5 + WHERE score >= 0.0 AND NOT (resource.deleted = true OR resource.disabled = true) RETURN resource {.*, __typename: labels(resource)[0]} LIMIT $limit ` + const myQuery = queryString(query) + const session = context.driver.session() const searchResultPromise = session.readTransaction(async transaction => { const postTransactionResponse = transaction.run(postCypher, { diff --git a/webapp/components/generic/SearchTag/SearchTag.vue b/webapp/components/generic/SearchTag/SearchTag.vue deleted file mode 100644 index a94431eea..000000000 --- a/webapp/components/generic/SearchTag/SearchTag.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/webapp/components/generic/SearchableInput/SearchableInput.vue b/webapp/components/generic/SearchableInput/SearchableInput.vue index 654deaad4..b0050b429 100644 --- a/webapp/components/generic/SearchableInput/SearchableInput.vue +++ b/webapp/components/generic/SearchableInput/SearchableInput.vue @@ -85,16 +85,6 @@ export default { return !isEmpty(this.previousSearchTerm) }, }, - watch: { - $route(to, from) { - console.log('to', to) - console.log('from', from) - // console.log(this.finalFilters) - if (to.query.hashtag) { - this.hashtag = to.query.hashtag - } - }, - }, methods: { isFirstOfType(option) { return ( @@ -167,7 +157,6 @@ export default { params: { id: item.id, slug: item.slug }, }) } else { - console.log('HIT¡') this.$router.push('?hashtag=' + item.id) } }) diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index 8aef52c1d..d73c993ec 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -64,158 +64,164 @@