다국어 웹사이트를 위한 간단한 검색 엔진(Gwoogl :p) 구축
23187 단어 noderestapijavascript
그중에서 우리는 미디어 콘텐츠(이미지 및 비디오)가 사용자에게 전달되는 원시 가치인 웹사이트를 보유하고 있습니다(제가 말하는 내용을 짐작하셨을 것입니다 😉). 따라서 "날씬한 대 뚱뚱한 레슬링"🙃을 찾는 방문자는 제목, 태그 및 설명이 무엇이든 모든 미디어에 관심을 갖고 검색에 빠지는 것을 인정할 것입니다. 예, 이 사례는 특히 증가하고 있습니다. 이러한 웹 사이트를 가지고 있고 다국어 검색 지원을 시작하지 않았다면 여기에서 출발점을 찾을 수 있습니다.
먼저 NodeJS를 웹 서버로 사용하고 MongoDB를 데이터베이스로 사용합니다. 이는 Word to Word API의 이점을 설명하기 위한 매우 기본적인 의미입니다.
// define your base query
const baseQuery = { d: false, a: true }
/**
* Approximate multilingual search based on indexed text fields: title, desc, tags
* @param {*} phrase sentence to search
* @param {*} exact whether search the exact sentence or separate terms
* @param {*} otherFields Of course you can add any other categorical fields to search
* @param {*} lang which language the phrase is in
* @return {Promise}
*/
this.gwoogl = async function (phrase, exact, otherFields, lang) {
// Limit search to newer content (ignoring very old content)
const daysBefore = 100
collection = mongoDB.collection('listing')
const since = getObjectId(daysBefore)
// quoted string value in Mongo to look for the exact match !
phrase = exact ? `"${phrase.trim()}"` : phrase.trim()
const query = JSON.parse(JSON.stringify(baseQuery)) // clone
// Collation is very important, it helps Mongo with searching natural languages
// something like "a car" can spot either "the car", "cars" etc
// Note that Collation at the moment is an index on the whole collection, ie
// You cannot apply different collation(s) on documents
let collation = lang === 'und' ? baseCollation : { locale: lang }
// THE FOLLOWING IS AN EXAMPLE
// HERE I'M FIRST SEARCHING FOR THE WHOLE PHRASE AS IS
// THEN I CALL TRANSLATION API ON THE FIRST TERM IN THE PHRASE. YOU CAN ITERATE ON EACH WORD IN THE SAME MANNER !!
// STACK AND FORMAT RESULTS AS YOU WISH !
query.$text = { $search: phrase }
query._id = { $gt: since }
if (lang !== 'und') query.lang = lang
// Dynamically adding other fields
for (const [key, value] of Object.entries(otherFields)) {
if (value !== 'und') query[key] = value
}
const docs = await collection
.find(query, { score: { $meta: 'textScore' } })
.collation(collation)
.project(baseProjection)
.sort({ score: { $meta: 'textScore' } })
.limit(21)
.toArray()
const count = await collection.countDocuments(query)
const result = { documents: docs, count: count, crossLangDocs: [] }
if (count < 6 && phrase.indexOf(' ') < 0) {
// Call translate API on each keyword, grab each query result (keywords), concatenate them as a single phrase and query again
let translations = translate({ limit: 10, source: lang, score: '0.5', word: phrase, target: 'fr', target: 'es', target: 'fi' })
for (const [lang, keywords] of Object.entries(translations)) {
collation = { locale: lang }
// Concatenating translations as a single phrase (you can do however you feel better)
phrase = keywords.join(' ')
query.$text = { $search: phrase }
const crossLangDocs = await collection
.find(query, { score: { $meta: 'textScore' } })
.collation(collation)
.project(baseProjection)
.sort({ score: { $meta: 'textScore' } })
.limit(3)
.toArray()
// console.log(crossLangDocs)
crossLangDocs.forEach((doc) => {
doc['crosslang'] = lang
})
result.crossLangDocs = result.crossLangDocs.concat(crossLangDocs)
}
}
return result
}
// Helpers
/**
* This function returns an ObjectId embedded with a given dateTime
* Accepts number of days since document was created
* Author: https://stackoverflow.com/a/8753670/1951298
* @param {Number} days
* @return {object}
*/
function getObjectId(days) {
const yesterday = new Date()
days = days || (process.env.NODE_ENV === 'localhost' ? 1000 : 14)
yesterday.setDate(yesterday.getDate() - days)
const hexSeconds = Math.floor(yesterday / 1000).toString(16)
return new ObjectId(hexSeconds + '0000000000000000')
}
고려하다
// Indexing title and description fields (ie fields to search for)
// collection#text must be indexed as the following:
const listingCollection = db.collection('listing')
await listingCollection.dropIndexes()
await listingCollection.createIndex({ title: 'text', cdesc: 'text' }, { weights: { title: 3, cdesc: 1 } })
// APIWrapper.js
// Requst Word to Word translator API
/*
* API wrapper
*
*/
import axios from "axios";
const translateParameters = (params) => {
return {
method: 'GET',
url: 'https://word-to-word-translator1.p.rapidapi.com/api/translate',
params,
headers: { 'X-RapidAPI-Key': 'YOUR RAPID API GOES HERE' }
}
};
const detectParameters = (params) => {
return {
method: 'GET',
url: 'https://word-to-word-translator1.p.rapidapi.com/api/detect_language',
params,
headers: { 'X-RapidAPI-Key': 'YOUR RAPID API GOES HERE' }
}
};
const translate = async (params) => {
return await axios.request(translateParameters(params))
}
const detect = async (params) => {
return await axios.request(detectParameters(params))
}
export { translate, detect }
최종 참고 사항
간단한 검색 엔진을 구축하는 것이 쉽지 않다는 것을 알 수 있습니다. 역시 자연어가 포함되기 때문입니다. 그러나 동시에 "인하우스"로 구축된 성능 솔루션은 매우 가능합니다!!
매우 작은 Gwoogl 검색 엔진을 사용하는 시나리오는 다음과 같습니다.
1- 사용자 입력 받기(실시간일 수 있음(솔직히 가능하다고 생각하지만 개인적으로 성능을 확인하기 위해 시도하지는 않음))
2- 일부 데이터 정리 및 조정(어간 추출, 표제어 추출 등)을 수행할 수 있습니다. 고맙게도 우리의 언어 감지 및 번역은 이와 관련하여 매우 강력하며 문맥 검색을 사용하므로 예를 들어 복수형을 그대로 두는 것이 좋습니다!
3- 입력 언어 감지(
Word2Word#detect
)4- 입력 단어 번역(
Word2Word#translate
)5- 키워드를 반복하고 결과를 쌓으세요!
만세, 이제 다국어 검색 엔진이 생겼습니다!
Reference
이 문제에 관하여(다국어 웹사이트를 위한 간단한 검색 엔진(Gwoogl :p) 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bacloud22/build-a-simple-search-engine-for-a-multilingual-website-4jfl텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)