mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-08 02:52:39 -05:00
Connected authors to the search index
refs https://github.com/TryGhost/Team/issues/1665 - Authors should be searchable. This change hooks up the Authors Content API with the search index
This commit is contained in:
parent
906f96827c
commit
dfc5b1c33d
2 changed files with 61 additions and 18 deletions
|
@ -7,12 +7,13 @@ export default class SearchIndex {
|
|||
this.storage = storage;
|
||||
|
||||
this.postsIndex = null;
|
||||
this.authorsIndex = null;
|
||||
|
||||
this.init = this.init.bind(this);
|
||||
this.search = this.search.bind(this);
|
||||
}
|
||||
|
||||
#updateIndex(data) {
|
||||
#updatePostIndex(data) {
|
||||
data.posts.forEach((post) => {
|
||||
this.postsIndex.addDoc({
|
||||
id: post.id,
|
||||
|
@ -26,11 +27,21 @@ export default class SearchIndex {
|
|||
this.storage.setItem('ease_search_last', data.posts[0].updated_at);
|
||||
}
|
||||
|
||||
#updateAuthorsIndex(data) {
|
||||
data.authors.forEach((author) => {
|
||||
this.authorsIndex.addDoc({
|
||||
id: author.id,
|
||||
name: author.name
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
// remove default stop words to search of *any* word
|
||||
elasticlunr.clearStopWords();
|
||||
|
||||
const url = `${this.apiUrl}/posts/?key=${this.apiKey}&limit=all&fields=id,slug,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext`;
|
||||
const postsAPIUrl = `${this.apiUrl}/posts/?key=${this.apiKey}&limit=all&fields=id,slug,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext`;
|
||||
const authorsAPIUrl = `${this.apiUrl}/authors/?key=${this.apiKey}&limit=all&fields=id,slug,name,profile_image`;
|
||||
|
||||
const indexDump = JSON.parse(this.storage.getItem('ease_search_index'));
|
||||
|
||||
|
@ -38,27 +49,37 @@ export default class SearchIndex {
|
|||
this.storage.removeItem('ease_last');
|
||||
|
||||
if (!indexDump) {
|
||||
return fetch(url)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
if (data.posts.length > 0) {
|
||||
this.postsIndex = elasticlunr();
|
||||
this.postsIndex.addField('title');
|
||||
this.postsIndex.addField('excerpt');
|
||||
this.postsIndex.setRef('id');
|
||||
const postsResponse = await fetch(postsAPIUrl);
|
||||
const posts = await postsResponse.json();
|
||||
|
||||
this.#updateIndex(data);
|
||||
}
|
||||
});
|
||||
if (posts.posts.length > 0) {
|
||||
this.postsIndex = elasticlunr();
|
||||
this.postsIndex.addField('title');
|
||||
this.postsIndex.addField('excerpt');
|
||||
this.postsIndex.setRef('id');
|
||||
|
||||
this.#updatePostIndex(posts);
|
||||
}
|
||||
|
||||
const authorsResponse = await fetch(authorsAPIUrl);
|
||||
const authors = await authorsResponse.json();
|
||||
|
||||
if (authors.authors.length > 0) {
|
||||
this.authorsIndex = elasticlunr();
|
||||
this.authorsIndex.addField('name');
|
||||
this.authorsIndex.setRef('id');
|
||||
|
||||
this.#updateAuthorsIndex(authors);
|
||||
}
|
||||
} else {
|
||||
this.postsIndex = elasticlunr.Index.load(indexDump);
|
||||
|
||||
return fetch(`${url}&filter=updated_at:>'${this.storage.getItem('ease_search_last').replace(/\..*/, '').replace(/T/, ' ')}'`
|
||||
return fetch(`${postsAPIUrl}&filter=updated_at:>'${this.storage.getItem('ease_search_last').replace(/\..*/, '').replace(/T/, ' ')}'`
|
||||
)
|
||||
.then(response => response.json())
|
||||
.then((data) => {
|
||||
if (data.posts.length > 0) {
|
||||
this.#updateIndex(data);
|
||||
this.#updatePostIndex(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -66,9 +87,14 @@ export default class SearchIndex {
|
|||
|
||||
search(value) {
|
||||
const posts = this.postsIndex.search(value, {expand: true});
|
||||
const authors = this.authorsIndex.search(value, {expand: true});
|
||||
|
||||
return {
|
||||
posts: posts.map((doc) => {
|
||||
return this.postsIndex.documentStore.docs[doc.ref];
|
||||
}),
|
||||
authors: authors.map((doc) => {
|
||||
return this.authorsIndex.documentStore.docs[doc.ref];
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,9 +12,16 @@ describe('search index', function () {
|
|||
const searchIndex = new SearchIndex({apiUrl, apiKey, storage: localStorage});
|
||||
|
||||
const scope = nock('http://localhost/ghost/api/content')
|
||||
.get('/posts/?key=secret_key&limit=all&fields=id,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext')
|
||||
.get('/posts/?key=secret_key&limit=all&fields=id,slug,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext')
|
||||
.reply(200, {
|
||||
posts: [{}]
|
||||
})
|
||||
.get('/authors/?key=secret_key&limit=all&fields=id,slug,name,profile_image')
|
||||
.reply(200, {
|
||||
authors: [{
|
||||
id: 'different_uniq',
|
||||
name: 'Barcelona Author'
|
||||
}]
|
||||
});
|
||||
|
||||
await searchIndex.init({apiUrl, apiKey});
|
||||
|
@ -22,19 +29,28 @@ describe('search index', function () {
|
|||
expect(scope.isDone()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('allows to search for indexed posts', async () => {
|
||||
test('allows to search for indexed posts and authors', async () => {
|
||||
const apiUrl = 'http://localhost/ghost/api/content';
|
||||
const apiKey = 'secret_key';
|
||||
const searchIndex = new SearchIndex({apiUrl, apiKey, storage: localStorage});
|
||||
|
||||
nock('http://localhost/ghost/api/content')
|
||||
.get('/posts/?key=secret_key&limit=all&fields=id,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext')
|
||||
.get('/posts/?key=secret_key&limit=all&fields=id,slug,title,excerpt,url,updated_at,visibility&order=updated_at%20desc&formats=plaintext')
|
||||
.reply(200, {
|
||||
posts: [{
|
||||
id: 'sounique',
|
||||
title: 'Awesome Barcelona Life',
|
||||
excerpt: 'We are sitting by the pool and smashing out search features'
|
||||
}]
|
||||
})
|
||||
.get('/authors/?key=secret_key&limit=all&fields=id,slug,name,profile_image')
|
||||
.reply(200, {
|
||||
authors: [{
|
||||
id: 'different_uniq',
|
||||
slug: 'barcelona-author',
|
||||
name: 'Barcelona Author',
|
||||
profile_image: 'https://url_to_avatar/barcelona.png'
|
||||
}]
|
||||
});
|
||||
|
||||
await searchIndex.init({apiUrl, apiKey});
|
||||
|
@ -42,6 +58,7 @@ describe('search index', function () {
|
|||
let searchResults = searchIndex.search('Barcelona');
|
||||
expect(searchResults.posts.length).toEqual(1);
|
||||
expect(searchResults.posts[0].title).toEqual('Awesome Barcelona Life');
|
||||
expect(searchResults.authors[0].name).toEqual('Barcelona Author');
|
||||
|
||||
searchResults = searchIndex.search('Nothing like this');
|
||||
expect(searchResults.posts.length).toEqual(0);
|
||||
|
|
Loading…
Add table
Reference in a new issue