Skip to content

Commit 08b4f8a

Browse files
committed
Refactor for bruk av samme tjeneste til alle søk
1 parent c84a8e8 commit 08b4f8a

13 files changed

+197
-184
lines changed

common/contentSearch.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { CmsContent } from './cms-documents/content';
2+
3+
export type ContentSearchHit = Pick<
4+
CmsContent,
5+
'contentKey' | 'versionKey' | 'displayName' | 'path'
6+
> & { score: number };
7+
8+
export type ContentSearchStatus = 'loading' | 'error' | 'success';
9+
10+
export type ContentSearchResult = {
11+
total: number;
12+
params: ContentSearchParams;
13+
status: ContentSearchStatus;
14+
hits: ContentSearchHit[];
15+
};
16+
17+
export type ContentSearchSort = 'score' | 'datetime' | 'name';
18+
19+
export type ContentSearchParams = {
20+
from: number;
21+
size: number;
22+
fullQuery?: boolean;
23+
categoryKey?: string;
24+
query?: string;
25+
sort?: ContentSearchSort;
26+
};

common/contentSearchResult.ts

-14
This file was deleted.

server/src/cms/CmsArchiveService.ts

+45-128
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
import { CmsCategoryListItem } from '../../../common/cms-documents/category';
2-
import {
3-
CategoryContentsResponse,
4-
CmsContent,
5-
CmsContentDocument,
6-
CmsContentListItem,
7-
} from '../../../common/cms-documents/content';
8-
import { CmsArchiveDbClient } from '../opensearch/CmsArchiveDbClient';
2+
import { CmsContent, CmsContentDocument } from '../../../common/cms-documents/content';
3+
import { CmsArchiveOpenSearchClient } from '../opensearch/CmsArchiveOpenSearchClient';
94
import { CmsBinaryDocument } from '../../../common/cms-documents/binary';
105
import { CmsArchiveSiteConfig } from './CmsArchiveSite';
116
import { sortVersions } from '../utils/sort';
127
import { AssetDocument, CmsCategoryDocument } from '../opensearch/types';
138
import { transformToCategoriesList } from './utils/transformToCategoriesList';
14-
import { QueryDslQueryContainer } from '@opensearch-project/opensearch/api/types';
15-
import { CmsCategoryRef } from '../../../common/cms-documents/_common';
16-
import { ContentSearchResult } from '../../../common/contentSearchResult';
9+
import { CmsCategoryPath } from '../../../common/cms-documents/_common';
10+
import { ContentSearchParams, ContentSearchResult } from '../../../common/contentSearch';
11+
import { buildContentSearchParams } from '../opensearch/queries/contentSearch';
1712

1813
type ConstructorProps = {
19-
client: CmsArchiveDbClient;
14+
client: CmsArchiveOpenSearchClient;
2015
siteConfig: CmsArchiveSiteConfig;
2116
};
2217

2318
export class CmsArchiveService {
24-
private readonly client: CmsArchiveDbClient;
19+
private readonly client: CmsArchiveOpenSearchClient;
2520
private readonly siteConfig: CmsArchiveSiteConfig;
2621

2722
private readonly categoriesIndex: string;
@@ -82,114 +77,36 @@ export class CmsArchiveService {
8277
.then((res) => transformToCategoriesList(res, this));
8378
}
8479

85-
public async getContentsForCategory(
86-
categoryKey: string,
87-
from: number = 0,
88-
size: number = 50,
89-
query?: string
90-
): Promise<CategoryContentsResponse | null> {
91-
const must: QueryDslQueryContainer[] = [
92-
{
93-
term: {
94-
isCurrentVersion: true,
95-
},
96-
},
97-
{
98-
term: {
99-
'category.key': categoryKey,
100-
},
101-
},
102-
];
103-
104-
if (query) {
105-
must.push({
106-
multi_match: {
107-
query,
108-
fields: ['displayName^10', 'xmlAsString'],
109-
type: 'phrase_prefix',
110-
},
111-
});
112-
}
113-
114-
return this.client.search<CmsContentListItem>({
115-
index: this.contentsIndex,
116-
from,
117-
size,
118-
_source_includes: ['contentKey', 'versionKey', 'displayName'],
119-
body: {
120-
sort: {
121-
name: 'asc',
122-
},
123-
query: {
124-
bool: {
125-
must,
126-
},
127-
},
128-
track_total_hits: true,
129-
},
130-
});
131-
}
132-
133-
public async contentSearch(
134-
query: string,
135-
from: number = 0,
136-
size: number = 50
137-
): Promise<ContentSearchResult> {
80+
public async contentSearch(params: ContentSearchParams): Promise<ContentSearchResult> {
13881
const result = await this.client.search<CmsContentDocument>({
82+
...buildContentSearchParams(params),
13983
index: this.contentsIndex,
140-
from,
141-
size,
142-
_source_excludes: ['xmlAsString', 'html', 'versions'],
143-
body: {
144-
sort: {
145-
_score: {
146-
order: 'desc',
147-
},
148-
},
149-
query: {
150-
bool: {
151-
must: [
152-
{
153-
term: {
154-
isCurrentVersion: {
155-
value: true,
156-
},
157-
},
158-
},
159-
{
160-
multi_match: {
161-
query,
162-
fields: ['displayName^10', 'xmlAsString'],
163-
type: 'phrase_prefix',
164-
},
165-
},
166-
],
167-
},
168-
},
169-
},
17084
});
17185

17286
if (!result) {
17387
return {
174-
query,
88+
params,
17589
total: 0,
176-
error: 'Søket feilet, prøv igjen',
90+
status: 'error',
17791
hits: [],
17892
};
17993
}
18094

95+
const hits = await Promise.all(
96+
result.hits.map(async (hit) => ({
97+
contentKey: hit.contentKey,
98+
versionKey: hit.versionKey,
99+
displayName: hit.displayName,
100+
score: hit._score || 0,
101+
path: await this.resolveCategoryPath(hit.category.key),
102+
}))
103+
);
104+
181105
return {
182-
query,
106+
params,
183107
total: result.total,
184-
hits: await Promise.all(
185-
result.hits.map(async (hit) => ({
186-
contentKey: hit.contentKey,
187-
versionKey: hit.versionKey,
188-
displayName: hit.displayName,
189-
score: hit._score || 0,
190-
path: await this.resolveCategoriesPath(hit.category.key),
191-
}))
192-
),
108+
status: 'success',
109+
hits,
193110
};
194111
}
195112

@@ -273,6 +190,26 @@ export class CmsArchiveService {
273190
return result.hits[0];
274191
}
275192

193+
async resolveCategoryPath(categoryKey: string): Promise<CmsCategoryPath> {
194+
const category = await this.getCategory(categoryKey);
195+
if (!category) {
196+
return [];
197+
}
198+
199+
const { key, superKey, title } = category;
200+
201+
const item = {
202+
key,
203+
name: title,
204+
};
205+
206+
if (!superKey) {
207+
return [item];
208+
}
209+
210+
return [...(await this.resolveCategoryPath(superKey)), item];
211+
}
212+
276213
private async fixContent(
277214
contentDocument: CmsContentDocument | null
278215
): Promise<CmsContent | null> {
@@ -284,7 +221,7 @@ export class CmsArchiveService {
284221
...contentDocument,
285222
versions: sortVersions(contentDocument),
286223
html: this.fixHtml(contentDocument.html),
287-
path: await this.resolveCategoriesPath(contentDocument.category.key),
224+
path: await this.resolveCategoryPath(contentDocument.category.key),
288225
};
289226
}
290227

@@ -297,24 +234,4 @@ export class CmsArchiveService {
297234
.replace(/(\r\n|\r|\n)/, '')
298235
.replace(/="\/(\d)+\//g, `="${this.siteConfig.basePath}/`);
299236
}
300-
301-
async resolveCategoriesPath(categoryKey: string): Promise<CmsCategoryRef[]> {
302-
const category = await this.getCategory(categoryKey);
303-
if (!category) {
304-
return [];
305-
}
306-
307-
const { key, superKey, title } = category;
308-
309-
const item = {
310-
key,
311-
name: title,
312-
};
313-
314-
if (!superKey) {
315-
return [item];
316-
}
317-
318-
return [...(await this.resolveCategoriesPath(superKey)), item];
319-
}
320237
}

server/src/cms/CmsArchiveSite.ts

+9-27
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { CmsArchiveDbClient } from '../opensearch/CmsArchiveDbClient';
1+
import { CmsArchiveOpenSearchClient } from '../opensearch/CmsArchiveOpenSearchClient';
22
import express, { Express, Response, Router } from 'express';
33
import { CmsArchiveService } from './CmsArchiveService';
4-
import { parseNumberParam, parseQueryParamsList } from '../utils/queryParams';
4+
import { parseQueryParamsList } from '../utils/queryParams';
55
import mime from 'mime';
66
import { HtmlRenderer } from '../site/ssr/htmlRenderer';
7+
import { transformQueryToContentSearchParams } from '../opensearch/queries/contentSearch';
78

89
export type CmsArchiveSiteConfig = {
910
name: string;
@@ -14,7 +15,7 @@ export type CmsArchiveSiteConfig = {
1415
type ContructorProps = {
1516
config: CmsArchiveSiteConfig;
1617
expressApp: Express;
17-
dbClient: CmsArchiveDbClient;
18+
dbClient: CmsArchiveOpenSearchClient;
1819
htmlRenderer: HtmlRenderer;
1920
};
2021

@@ -78,32 +79,13 @@ export class CmsArchiveSite {
7879
return res.send(contentVersion);
7980
});
8081

81-
router.get('/contentForCategory/:categoryKey', async (req, res) => {
82-
const { categoryKey } = req.params;
83-
const { from, size, query } = req.query;
84-
85-
const contentList = await this.cmsArchiveService.getContentsForCategory(
86-
categoryKey,
87-
parseNumberParam(from),
88-
parseNumberParam(size),
89-
query as string
90-
);
91-
if (!contentList) {
92-
return res
93-
.status(404)
94-
.send(`Contents for category with key ${categoryKey} not found`);
95-
}
96-
97-
return res.send(contentList);
98-
});
99-
100-
router.get('/search/simple', async (req, res) => {
101-
const { query } = req.query;
102-
if (!query) {
103-
return res.status(400).send('Parameter "query" is required');
82+
router.get('/search', async (req, res) => {
83+
const params = transformQueryToContentSearchParams(req);
84+
if (!params) {
85+
return res.status(400).send('Invalid parameters for search request');
10486
}
10587

106-
const result = await this.cmsArchiveService.contentSearch(query as string);
88+
const result = await this.cmsArchiveService.contentSearch(params);
10789

10890
return res.send(result);
10991
});

server/src/cms/utils/transformToCategoriesList.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const transformToListItem = async (
1313
title,
1414
categories,
1515
contentCount: contents.length,
16-
path: superKey ? await archiveService.resolveCategoriesPath(superKey) : [],
16+
path: superKey ? await archiveService.resolveCategoryPath(superKey) : [],
1717
};
1818
};
1919

server/src/opensearch/CmsArchiveDbClient.ts server/src/opensearch/CmsArchiveOpenSearchClient.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const logException = (e: unknown) => {
2121
}
2222
};
2323

24-
export class CmsArchiveDbClient {
24+
export class CmsArchiveOpenSearchClient {
2525
private readonly openSearchClient: ClientTypeNew;
2626

2727
constructor() {

0 commit comments

Comments
 (0)