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.