ABOUT ME

ํ”„๋กœ๊ทธ๋ž˜๋ฐ & ๋ณด์•ˆ ๊ณต๋ถ€

Today
Yesterday
Total
  • [Algolia, Firebase, React Native] Algolia ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฒ€์ƒ‰ํ•˜๊ธฐ
    PROGRAMMING/๊ธฐํƒ€ 2022. 1. 25. 19:51

     

    ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Node.js ๊ธฐ๋ฐ˜์œผ๋กœ Algolia ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์„ ๊ตฌํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    • npm 6.4.11
    • algoliasearch 4.12.0
    • React Native

     

    Algolia ์™€ Firebase ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  index ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์ด์ „ ํฌ์ŠคํŒ…๋“ค์„ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

    2022.01.25 - [PROGRAMMING/๊ธฐํƒ€] - [Firebase, Algolia] Cloud Extension ์œผ๋กœ Algolia ์—ฐ๊ฒฐํ•ด์„œ ๊ฒ€์ƒ‰ ๊ตฌํ˜„

     

    [Firebase] Cloud Extension ์œผ๋กœ Algolia ์—ฐ๊ฒฐํ•ด์„œ ๊ฒ€์ƒ‰ ๊ตฌํ˜„

    Firebase ๋Š” text ๊ฒ€์ƒ‰์ด exact search ๊ฒ€์ƒ‰๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. https://firebase.google.com/docs/firestore/solutions/search ๋”ฐ๋ผ์„œ ๊ฒ€์ƒ‰ ์—…์ฒด์ธ Algolia ๋ฅผ ์—ฐ๋™ํ•˜์—ฌ ์‚ฌ์šฉํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์œ„ ๋งํฌ์—์„œ๋Š” ๋‹ค๋ฅธ..

    iforint.tistory.com

     

    ์ด๋ ‡๊ฒŒ ์ž˜ ์—ฐ๊ฒฐ๋งŒ ํ•ด๋’€๋‹ค๋ฉด, ๊ฒ€์ƒ‰์€ ์ •๋ง์ด์ง€ ์•„์ฃผ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. (๋“œ๋””์–ด ๊ธด ์—ฌ์ •์„ ๋๋‚ผ ๋•Œ๊ฐ€..)

     

     

    1. algoliasearch ์„ค์น˜

    $ npm install algoliasearch

    npm ์œผ๋กœ algoliasearch ๋ฅผ ์„ค์น˜ํ•ด์ค๋‹ˆ๋‹ค. (https://www.npmjs.com/package/algoliasearch)

     

     

    2. Algolia ์„ค์ •: client, index

    ๋‹ค์Œ๊ณผ ๊ฐ™์ด algolia search client ๋ฅผ APP ID ์™€ API Key ๋ฅผ ๊ฐ€์ง€๊ณ  ๋งŒ๋“ค์–ด์ฃผ๊ณ , ๊ฒ€์ƒ‰ํ•  index ๋ฅผ ๋“ฑ๋กํ•ด์ค๋‹ˆ๋‹ค.

    ์ €์˜ ๊ฒฝ์šฐ APP ID ์™€ Search-Only API Key ๋ฅผ Front-end ์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•  ๊ฒƒ์ด์ง€๋งŒ, ๊ทธ๋ž˜๋„ ์ด ์ •๋ณด๋“ค์„ ์•ฑ์— ๋‘๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•˜์—ฌ Firebase Firestore ์— ๋„ฃ์–ด๋‘๊ณ  ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•˜๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. (์›๋ž˜ firestore ์‚ฌ์šฉํ•ด์„œ firestore ์— ๋„ฃ์–ด๋‘” ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

    import firestore from '@react-native-firebase/firestore';
    
    const algoliasearch = require("algoliasearch");
    var collectionIndex;
    
    async function initAlgolia() {
        // Get algolia keys first
        const doc = await firestore().collection('Algolia').doc('algolia').get();
        const algolia = doc.data();
        
        // make algolia client and target index
        searchClient = algoliasearch(algolia.AppId, algolia.APIKey);
        const indexName = 'dev_title';
        collectionIndex = searchClient.initIndex(indexName);
    };

     

     

    3. Search ๊ธฐ๋Šฅ ๊ตฌํ˜„

    search ๋Š” ์ •๋ง ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ collectionIndex.search() ์ด๊ณ , ์ด ํ•จ์ˆ˜๋Š” query ์™€ options ์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

    (https://www.algolia.com/doc/api-reference/api-methods/search/)

     

    ๊ทธ๋ƒฅ ๊ฒ€์ƒ‰์„ ํ•˜๋ฉด ๋“ฑ๋ก๋˜์–ด ์žˆ๋Š” ๋ชจ๋“  ์ •๋ณด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๊ฒ€์ƒ‰์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    ์ €์˜ ๊ฒฝ์šฐ, ๋‹ค์Œ์˜ 2๊ฐ€์ง€๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒ€์ƒ‰์„ ๊ตฌํ˜„ํ•˜๋ ค ํ–ˆ์Šต๋‹ˆ๋‹ค.

    • title ์—์„œ๋งŒ ๊ฒ€์ƒ‰
    • uid ์ •๋ณด๊ฐ€ USER_ID ์ธ ๊ฒƒ๋“ค๋งŒ ๊ฒ€์ƒ‰

     

    ์ฆ‰, ํŠน์ • ์‚ฌ์šฉ์ž์˜ title ์ด๋ผ๋Š” ์š”์†Œ ์ค‘์—์„œ ๊ฒ€์ƒ‰์„ ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

    ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด search ์—์„œ ์ง€์›ํ•˜๋Š” Search API Parameters ์ค‘, restrictSearchableAttributes ์™€ filters ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

    (Algolia Search API Parameters: https://www.algolia.com/doc/api-reference/search-api-parameters/)

    const userFilter = `uid:${USER_ID}`
    
    /**
     * Search by title
     * @param {string} query
     * @returns {Promise}
     */
     async function searchTiccleWithAlgolia(query) {
        // search with Algolia
        const result = await collectionIndex.search(query, {
            restrictSearchableAttributes: [
                "title", // ONLY look at title
            ],
            filters: userFilter,
        });
        var metadataList = [];
        result.hits.forEach(element => {
            const record = {
                id: element.objectID,
                title: element.title,
            }
            metadataList.push(record);
        });
        // return search result
        return new Promise(resolve => {
            resolve(metadataList);
        });
    }

     

    3-1) restrictSearchableAttributes

    restrictSearchableAttributes ๋ฅผ parameter ๋กœ ์ฃผ๋ฉด, ํ•ด๋‹น field ๋“ค์—์„œ๋งŒ ๊ฒ€์ƒ‰์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

    ๋‹จ, ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” Algolia ์—์„œ Searchable attributes ์— ํ•ด๋‹น ํ•„๋“œ๋“ค์„ ๋“ฑ๋กํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์ €๋Š” dashboard ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. (index -> Configuration -> Searchable attributes)

     

     

     

    3-2) filters

    filters ๋Š” SQL ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฒฐ๊ณผ๋ฅผ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ €์˜ ๊ฒฝ์šฐ, ํŠน์ • uid ์— ๋Œ€ํ•œ ๊ฒƒ๋“ค๋งŒ ๊ฒฐ๊ณผ๋กœ ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ filters ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค ํ–ˆ์Šต๋‹ˆ๋‹ค.

    ๊ทธ๋Ÿฐ๋ฐ ๊ณต์‹ ๋ฌธ์„œ์˜ ์„ค๋ช…์„ ๋ณด๋ฉด, ํ•„ํ„ฐ๋ฅผ ํ•˜๋ ค๋Š” field ์˜ ์ด๋ฆ„์— string value ๊ฐ€ ํฌํ•จ๋œ๋‹ค๋ฉด attributesForFaceting ์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

    Format: facetName:{facetValue}
    When ${facetName} contains string values, you need to declare it in attributesForFaceting

    ๊ทธ๋ž˜์„œ index ์˜ Configuration ์˜ Attributes for faceting ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด uid ํ•„๋“œ๋ฅผ ๋“ฑ๋กํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

    (์ด๋Š” index.setSettings() ๋กœ ํ•ด์ฃผ์–ด๋„ ๋˜์ง€๋งŒ, ์ €์˜ ๊ฒฝ์šฐ Search-Only API Key ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ setting ์„ ํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ๋„ ํ–ˆ๊ณ , ํ•œ๋ฒˆ๋งŒ ์„ค์ •ํ•˜๋ฉด ๋˜๋‹ˆ dashboard ๋ฅผ ํ†ตํ•ด ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.)

    (index -> Configuration -> Facets -> Attributes for faceting)

     

     

     

    ์ด๋ ‡๊ฒŒ ์„ค์ •๊นŒ์ง€ ๋‹ค ํ•ด์ฃผ๋ฉด ์œ„์˜ ์ฝ”๋“œ๋กœ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

     


    Algolia ๋Š” Firebase ์—์„œ full text ๊ฒ€์ƒ‰์ด ์•ˆ๋ผ์„œ ๋Œ€์•ˆ์ฑ…์œผ๋กœ ์‚ฌ์šฉํ•œ ๊ฒƒ์ธ๋ฐ, ์ฒ˜์Œ์—๋Š” ๋ฒˆ๊ฑฐ๋กญ๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์—ˆ์œผ๋‚˜ ๋Œ์•„๋ณด๋‹ˆ ์™œ ๊ฒ€์ƒ‰ ์—…์ฒด๋ฅผ ๋”ฐ๋กœ ์—ฐ๊ฒฐํ•ด์„œ ์“ฐ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ๊ฐ™์€ ๊ฒ€์ƒ‰ query ๋ฉด cache ๋ฅผ ๋‘๋Š”์ง€ (์ •ํ™•ํžˆ ์ฐพ์•„๋ณด์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค) ๊ฒฐ๊ณผ๊ฐ€ ๋” ๋นจ๋ฆฌ ์˜ค๋”๋ผ๊ณ ์š”. ์—ฐ๊ฒฐํ•˜๋Š” ์ž‘์—…๋„ ์ฒ˜์Œ์— ์ž˜ ํ•ด๋‘๋ฉด ๋’ค๋กœ๋Š” ํŠน๋ณ„ํžˆ ์†๋ณผ ๊ฒƒ์ด ์—†๊ธฐ๋„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

     

    ์•„๋ฌดํŠผ ์ด๋ ‡๊ฒŒ Firebase ๋ฅผ Algolia ์— ์—ฐ๊ฒฐํ•˜๊ณ , ๊ฒ€์ƒ‰์„ ๊ตฌํ˜„ํ•˜์—ฌ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ํ™•์ธํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค!

     

    ๋Œ“๊ธ€

Designed by Tistory.