Add chips to improve precision

This commit is contained in:
Sijmen 2018-10-23 13:16:23 +02:00
parent 3cd7b78d81
commit 9839634e1b
6 changed files with 84 additions and 25 deletions

View file

@ -9,7 +9,6 @@ import click
from .question import Question
from .question_search import QuestionSearch
app = Flask(__name__)
connections.create_connection(hosts=["localhost"])
@ -39,6 +38,15 @@ def index():
"category": {
"terms": {"field": "category"},
},
"suggestions": {
"significant_terms": {
"field": "body",
"mutual_information": {
"include_negatives": True,
},
"size": 40,
},
}
},
})
@ -51,6 +59,9 @@ def index():
for bucket in response.aggregations.category.buckets
]
suggestions = [{"key": bucket.key, "count": bucket.doc_count}
for bucket in response.aggregations.suggestions.buckets]
date_facets = []
results = []
@ -59,14 +70,17 @@ def index():
url = Question.url(hit)
results.append({
"id": hit.meta.id, "score": hit.meta.score,
"title": hit.title, "body": summary,
"category": hit.category, "date": hit.date,
"id": hit.meta.id, "score": hit.meta.score, "title": hit.title,
"body": summary, "category": hit.category, "date": hit.date,
"url": url,
})
return jsonify(
facets={"months": date_facets, "categories": category_facets},
facets={
"months": date_facets,
"categories": category_facets,
},
suggestions=suggestions,
results=results,
hits=round_sigfig(response.hits.total, 4),
took=response.took / 1000,

View file

@ -3,7 +3,10 @@ from elasticsearch_dsl import Document, Date, Keyword, Text
class Question(Document):
title = Text(analyzer="snowball")
body = Text(analyzer="snowball")
body = Text(
analyzer="snowball",
fielddata=True,
)
category = Keyword()
date = Date()

View file

@ -1,5 +1,12 @@
<template>
<div class="body">
<div class="suggestions">
<div v-for="suggestion in json.suggestions" class="suggestion"
@click="appendToQuery(suggestion.key)">
{{suggestion.key}}
</div>
</div>
<div class="result-count">
Ongeveer {{hits}} resultaten ({{responseTime.toFixed(2)}} seconden)
</div>
@ -30,6 +37,8 @@
</a>
</div>
</div>
<!--pre>{{JSON.stringify(json, null, 2)}}</pre-->
</div>
</div>
</template>
@ -40,19 +49,25 @@ import {Component, Prop, Watch} from "vue-property-decorator";
@Component
export default class ResultBody extends Vue {
@Prop() query;
@Prop() value;
json = null;
activeCategories = [];
hits = 0;
results = [];
responseTime = 0;
facets = {};
@Watch("query")
@Watch("value")
async onQueryChanged(value) {
await this.search();
}
@Watch("$route")
async onRouteChanged() {
this.$emit("input", this.$route.query.q);
}
async toggleCategory(category) {
const name = category.category;
@ -67,7 +82,7 @@ export default class ResultBody extends Vue {
}
async search() {
const query = encodeURIComponent(this.query);
const query = encodeURIComponent(this.value);
let queryString = `?q=${query}`;
if (this.activeCategories.length > 0) {
@ -79,12 +94,16 @@ export default class ResultBody extends Vue {
const url = `/api/${queryString}`;
let response = await fetch(url);
let json = await response.json();
this.json = await response.json();
this.results = json.results;
this.hits = json.hits;
this.responseTime = json.took;
this.facets = json.facets;
this.results = this.json.results;
this.hits = this.json.hits;
this.responseTime = this.json.took;
this.facets = this.json.facets;
}
appendToQuery(value) {
this.$emit("input", `${this.value} AND ${value}`)
}
}
</script>
@ -171,4 +190,25 @@ export default class ResultBody extends Vue {
.category__count {
text-align: right;
}
.suggestions {
display: flex;
flex-flow: row wrap;
max-width: 1000px;
margin: 12px 0;
height: 70px;
overflow-y: hidden;
}
.suggestion {
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 12px;
background-color: #f8f8f8;
padding: 7px 16px;
margin: 2px;
cursor: pointer;
}
</style>

View file

@ -1,7 +1,7 @@
<template>
<div>
<top-bar v-model="query" />
<result-body :query="query" />
<result-body v-model="query" />
</div>
</template>

View file

@ -37,8 +37,10 @@ import {Component, Prop} from "vue-property-decorator";
export default class TopBar extends Vue {
@Prop() value = "";
search(event) {
search (event) {
if (event.target.value.trim().length > 0) {
this.$emit("input", event.target.value)
}
}
}
</script>

View file

@ -1763,9 +1763,9 @@ copy-descriptor@^0.1.0:
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
copy-webpack-plugin@^4.0.1:
version "4.5.3"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.3.tgz#14a224d205e46f7a79f7956028e1da6df2225ff2"
integrity sha512-VKCiNXQcc8zyznaepXfKpCH2cZD+/j3T3B+gsFY97P7qMlEsj34wr/sI9OCG7QPUUh7gAHVx3q8Q1rdQIDM4bA==
version "4.5.4"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.5.4.tgz#f2b2782b3cd5225535c3dc166a80067e7d940f27"
integrity sha512-0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ==
dependencies:
cacache "^10.0.4"
find-cache-dir "^1.0.0"
@ -4538,12 +4538,12 @@ node-libs-browser@^2.0.0:
vm-browserify "0.0.4"
node-notifier@^5.1.2:
version "5.2.1"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea"
integrity sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==
version "5.3.0"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01"
integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==
dependencies:
growly "^1.3.0"
semver "^5.4.1"
semver "^5.5.0"
shellwords "^0.1.1"
which "^1.3.0"
@ -5971,7 +5971,7 @@ selfsigned@^1.9.1:
dependencies:
node-forge "0.7.5"
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1:
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==