query string for searches changed and basics for Hashtag search added

This commit is contained in:
Moriz Wahl 2020-01-06 16:46:43 +01:00
parent bc3aa519d0
commit 71c9d92aea
8 changed files with 68 additions and 14 deletions

View File

@ -6,7 +6,13 @@ export default {
const { query, limit } = args const { query, limit } = args
const { id: thisUserId } = context.user const { id: thisUserId } = context.user
// see http://lucene.apache.org/core/8_3_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description // see http://lucene.apache.org/core/8_3_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description
const myQuery = query + '*' const myQuery = query
.replace(/\s+/g, ' ')
.replace(/[[@#:*~\\$|^\]?/"'(){}+?!,.-]/g, '')
.split(' ')
.map(s => '"' + s + '"*')
.join(' ')
// console.log(myQuery)
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
@ -40,6 +46,15 @@ export default {
RETURN resource {.*, __typename: labels(resource)[0]} RETURN resource {.*, __typename: labels(resource)[0]}
LIMIT $limit LIMIT $limit
` `
/*
const tagCypher = `
MATCH (resource:Tag)
WHERE resource.id CONTAINS $query
AND NOT(resource.deleted = true OR resource.disabled = true)
RETURN resource {.*, __typename: labels(resource)[0]}
LIMIT $limit
`
*/
const session = context.driver.session() const session = context.driver.session()
const searchResultPromise = session.readTransaction(async transaction => { const searchResultPromise = session.readTransaction(async transaction => {
@ -53,14 +68,20 @@ export default {
limit, limit,
thisUserId, thisUserId,
}) })
return Promise.all([postTransactionResponse, userTransactionResponse]) /*
const tagTransactionResponse = transaction.run(tagCypher, {
query: query,
limit,
}) */
return Promise.all([postTransactionResponse, userTransactionResponse]) //, tagTransactionResponse
}) })
try { try {
const [postResults, userResults] = await searchResultPromise const [postResults, userResults] = await searchResultPromise //, tagResults
log(postResults) log(postResults)
log(userResults) log(userResults)
return [...postResults.records, ...userResults.records].map(r => r.get('resource')) // log(tagResults)
return [...postResults.records, ...userResults.records].map(r => r.get('resource')) //, ...tagResults.records
} finally { } finally {
session.close() session.close()
} }
@ -68,7 +89,27 @@ export default {
}, },
} }
/* /* order users by closest geolocation could look like this
MATCH (u1:User { id: $thisUserId })-[:IS_IN]->(l1:Location)
MATCH (u2:User)-[:IS_IN]->(l2:Location)
WHERE NOT(u2.id = $thisUserId)
AND NOT (u2.deleted = true OR u2.disabled = true
OR (u1)-[:BLOCKED]-(u2))
WITH point({longitude: l1.lng, latitude: l1.lat}) AS P1,
point({longitude: l2.lng, latitude: l2.lat}) AS P2,
u2 AS otherUsers
WITH distance(P1, P2) AS Distance,
otherUsers AS users
ORDER BY Distance
RETURN users
*/
/* This query is to test if the calculation of distances works.
See:
https://github.com/Human-Connection/Human-Connection/issues/2587
MATCH (u1:User { name: 'Huey' })-[:IS_IN]->(l1:Location) MATCH (u1:User { name: 'Huey' })-[:IS_IN]->(l1:Location)
MATCH (u2:User)-[:IS_IN]->(l2:Location) MATCH (u2:User)-[:IS_IN]->(l2:Location)
WHERE NOT(u2.name = 'Huey') WHERE NOT(u2.name = 'Huey')

View File

@ -1,4 +1,4 @@
union SearchResult = Post | User union SearchResult = Post | User | Tag
type Query { type Query {
findResources(query: String!, limit: Int = 5): [SearchResult]! findResources(query: String!, limit: Int = 5): [SearchResult]!

View File

@ -1,5 +1,5 @@
<template> <template>
<ds-flex-item> <ds-flex-item class="search-heading">
<ds-heading soft size="h5"> <ds-heading soft size="h5">
{{ $t(`search.heading.${resourceType}`) }} {{ $t(`search.heading.${resourceType}`) }}
</ds-heading> </ds-heading>

View File

@ -6,7 +6,7 @@
<ds-flex-item class="search-option-meta" width="280px"> <ds-flex-item class="search-option-meta" width="280px">
<ds-flex> <ds-flex>
<ds-flex-item> <ds-flex-item>
<ds-text size="small" color="softer" class="search-meta"> <ds-text size="small" color="softer" class="search-post-meta">
<span style="text-align: right;"> <span style="text-align: right;">
<b>{{ option.commentsCount }}</b> <b>{{ option.commentsCount }}</b>
<base-icon name="comments" /> <base-icon name="comments" />
@ -18,7 +18,7 @@
</ds-text> </ds-text>
</ds-flex-item> </ds-flex-item>
<ds-flex-item> <ds-flex-item>
<ds-text size="small" color="softer" align="right"> <ds-text size="small" color="softer" align="right" class="search-post-author">
{{ option.author.name | truncate(32) }} - {{ option.author.name | truncate(32) }} -
{{ option.createdAt | dateTime('dd.MM.yyyy') }} {{ option.createdAt | dateTime('dd.MM.yyyy') }}
</ds-text> </ds-text>
@ -49,7 +49,7 @@ export default {
flex-direction: column; flex-direction: column;
} }
} }
.search-meta { .search-post-meta {
float: right; float: right;
padding-top: 2px; padding-top: 2px;
white-space: nowrap; white-space: nowrap;

View File

@ -49,6 +49,12 @@
> >
<search-post :option="option" /> <search-post :option="option" />
</span> </span>
<span
v-if="option.__typename === 'Tag'"
:class="{ 'extra-space': isFirstOfType(option), 'flex-span': true }"
>
<search-tag :option="option" />
</span>
</template> </template>
</ds-select> </ds-select>
</div> </div>
@ -59,12 +65,14 @@
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
import SearchHeading from '~/components/generic/SearchHeading/SearchHeading.vue' import SearchHeading from '~/components/generic/SearchHeading/SearchHeading.vue'
import SearchPost from '~/components/generic/SearchPost/SearchPost.vue' import SearchPost from '~/components/generic/SearchPost/SearchPost.vue'
import SearchTag from '~/components/generic/SearchTag/SearchTag.vue'
import HcUser from '~/components/User/User.vue' import HcUser from '~/components/User/User.vue'
export default { export default {
components: { components: {
SearchHeading, SearchHeading,
SearchPost, SearchPost,
SearchTag,
HcUser, HcUser,
}, },
props: { props: {
@ -104,10 +112,10 @@ export default {
}, },
handleInput(event) { handleInput(event) {
clearTimeout(this.searchProcess) clearTimeout(this.searchProcess)
this.value = event.target ? event.target.value.trim() : '' this.value = event.target ? event.target.value.replace(/\s+/g, ' ').trim() : ''
this.isOpen = true this.isOpen = true
this.unprocessedSearchInput = this.value this.unprocessedSearchInput = this.value
if (isEmpty(this.value) || this.value.length < 3) { if (isEmpty(this.value) || this.value.replace(/\s+/g, '').length < 3) {
return return
} }
this.searchProcess = setTimeout(() => { this.searchProcess = setTimeout(() => {

View File

@ -19,6 +19,9 @@ export const findResourcesQuery = gql`
... on User { ... on User {
...user ...user
} }
... on Tag {
id
}
} }
} }
` `

View File

@ -518,7 +518,8 @@
"failed": "Nichts gefunden", "failed": "Nichts gefunden",
"heading": { "heading": {
"Post": "Beiträge", "Post": "Beiträge",
"User": "Benutzer" "User": "Benutzer",
"Tag": "Hashtags"
} }
}, },
"components": { "components": {

View File

@ -202,7 +202,8 @@
"failed": "Nothing found", "failed": "Nothing found",
"heading": { "heading": {
"Post": "Posts", "Post": "Posts",
"User": "Users" "User": "Users",
"Tag": "Hashtags"
} }
}, },
"settings": { "settings": {