서론
보통 개발자들은 글을 작성할 때 다양한 편의기능을 통해 일목요연하게 정리한다.
예를 들어, 코드와 같은 경우에는 Hello World 등으로 구분하여 표현하거나 사용한 기술스택들을 태그하여 작성하기도 한다.
나는 이번 Team Project에서 커뮤니티를 구축하면서 게시물들을 작성할 때 어떻게 편의기능들을 만들었고 이러한 게시물들을 검색하는 시스템을 구축했는 지 정리해보려고 한다.
게시물 작성 시 편의기능 추가
언어: JavaScript
라이브러리: React
let tmp = content.split("```");
return(
tmp.map( (text,index) => {
// 본문
if( index % 2 == 0){
return(
<pre style={{ fontFamily: "inherit" ,verticalAlign: 'middle' }}>
<Grid container spacing={2}>
{renderLine(text)}
</Grid>
</pre>
);
}
// 코드
else {
text = text.replace('\n','');
return(
<Typography key={index} sx={{ p: 2 ,backgroundColor: 'rgb(240,240,240)' }}>
<pre style={{ fontFamily: 'inherit' }}>{renderLine(text)}</pre>
</Typography>
);
}
});
);
const renderLine = (text) => {
return(
text.split("\n").map( line => {
return(
<Grid item xs={12} sx={{ flexDirection: 'row' ,display: 'flex' ,justfiyContent: 'center' ,alignItems: 'center' }}>
{renderStrongText(line)}
</Grid>
);
})
);
}
**text**의 형식을 확인하여 일반 텍스트와 굵은 글씨의 텍스트를 구분하여 직접 배열에 넣어줬다.const renderStrongText = (value) => {
let text = value;
const regExp = /\*\*.{0,}\*\*/m;
let s = [];
// **text** 모두 찾을때까지
while( text && text.length > 0 ){
if( regExp.test(text) ){
const startIndex = text.search(regExp);
// normal text
s.push({ "type" : "normal" , "text" : text.substring(0,startIndex) });
let restText = text.substring(startIndex+2,text.length);
const finIndex = restText.search(/\*\*/);
// // strong text
s.push({ "type" : "strong", "text" : restText.substring(0,finIndex) })
text = restText.substring(finIndex+2,restText.length);
}
else {
s.push({ "type": "normal", "text" : text });
text = "";
}
}
return(
s.map( item => {
if( item.type === "normal")
return <pre style={{ fontFamily: 'inherit' }}>{item.text}</pre>
else if( item.type === "strong")
return <b style={{ fontFamily: 'inherit' ,fontWeight: 'bold'}}>{item.text}</b>
})
)
}
게시물 검색 시스템
게시물 검색은 크게 3가지로 나누었다.
일반 검색으로 검색한 경우 공백 기준으로 글자를 구분하여 "일반","검색"으로 나누어 모두 검색하도록 하였다.일반 검색 -> "일반 검색" )[react]로 검색한 경우 정확한 문구로 검색과 같이 [] 안에 있는 단어를 태그로 가지는 게시물들을 검색하였다.[react] -> %react% 로 변환하여 호출하고 그에 따라 서버에서 처리하였다.작성코드
String[] s = sentence.split(" ");
List<Post> findPosts = new ArrayList<Post>();
boolean exact_phrase_flag = false;
String exact_phrase_concat = "";
// 검색된 문장을 공백 기준으로 모두 검색하여 결과에 추가한다.
for ( String keyword : s ) {
// 1. [태그] 검색일 경우 -> %태그% 로 변환하여 요청받음.
if( keyword.startsWith("%") && keyword.endsWith("%") ) {
// [tag] -> tag
String tag = keyword.substring(1,keyword.length()-1);
Optional<List<Post>> result = postRepository.findAllByTagsContaining(tag);
addSearchResults(findPosts,result);
}
// 2. "정확한 문구" 검색일 경우
// ex) "react"
else if( keyword.startsWith("\"") && keyword.endsWith("\"")){
// "react" -> react
String exact_phrase = keyword.substring(1,keyword.length()-1);
Optional<List<Post>> result = postRepository.findAllByTitleContainingOrContentContaining(exact_phrase,exact_phrase);
addSearchResults(findPosts,result);
}
// ex) "react and native" -> "react
else if( keyword.startsWith("\"")){
exact_phrase_flag = true;
exact_phrase_concat += keyword.substring(1);
}
// native"
else if( keyword.endsWith("\"")){
exact_phrase_concat += " " + keyword.substring(0,keyword.length()-1);
Optional<List<Post>> result = postRepository.findAllByTitleContainingOrContentContaining(exact_phrase_concat,exact_phrase_concat);
addSearchResults(findPosts,result);
// 초기화
exact_phrase_flag = false;
exact_phrase_concat = "";
}
// and
else if( exact_phrase_flag ){
exact_phrase_concat += " " + keyword;
}
// n. 일반적인 검색
else {
Optional<List<Post>> result = postRepository.findAllByTitleContainingOrContentContaining(keyword, keyword);
addSearchResults(findPosts,result);
}
}
return findPosts;