php - Algolia 地理搜索不工作

标签 php search full-text-indexing algolia

我在使用之前工作正常的 Algolia 地理搜索功能时遇到了一些问题。这是 record of interest .

我也将其索引为 described by the doc为了让我按最近的距离对它进行排序:

'attributesToIndex' => ['name', 'description', 'geo']

在我的客户端脚本中:

let settings = {
   aroundLatLng: '10.309813,123.893154', 
   getRankingInfo: true, 
   aroundRadius: 2000 
};

index.search(keyword, settings, (err, data) => {
   console.log(data);
});

但这给了我 0 命中。注意 aroundLatLng 值——它与 record of interest 中的值相同.

我是不是漏掉了什么?

最佳答案

我已经按照文档中给出的要求在 node.js 中实现了相同的要求,并且工作正常。 在这里,我正在复制我的整个代码。希望对您有所帮助。

代码

   /*
      I have used async.water model to create the setting of the index and then searching data as per given parameter. few function is custom so no need to bother about that. read each line patently.
   */
    try {
        var self = this;
        var post = req.body;
        var user_id = post.user_id;
        var created_mode = post.user_mode == 'requester' ? 'provider' : 'requester';
        var kword = post.kword;
        var geo = post.geo_loc;
        var aroundLatLng = post.aroundLatLng;
        var aroundRadius = !cmnFn.empty(post.radious) ? post.radious : 4500;
        var hitsPerPage = !cmnFn.empty(post.hitsPerPage) ? post.hitsPerPage : 20;
        var offset = !cmnFn.empty(post.offset) ? post.offset : 0;
        var length = !cmnFn.empty(post.length) ? post.length : 50;
        var budget_from = !cmnFn.empty(post.budget_from) ? post.budget_from : 0;
        var budget_to = !cmnFn.empty(post.budget_to) ? post.budget_to : 0;
        var day_preference = !cmnFn.empty(post.day_preference) ? post.day_preference : '';
        var time_preference = !cmnFn.empty(post.time_preference) ? post.time_preference : '';
        var start_date = !cmnFn.empty(post.start_date) ? post.start_date : '';

job_index 是在 Algolia 上创建的索引

        var job_index = algClient.initIndex('jobs');


        var cond = {};

如果您正在使用 facet & filter,那么您需要使用 filter key 来执行您的条件,就像您在 sql 中使用 where clouse 所做的一样

        cond.filters = 'created_mode:"' + created_mode + '" AND (NOT user_id:"' + user_id + '")';
        // Query which need to be search
        if (!cmnFn.empty(kword)) {
            cond.query = !cmnFn.empty(post.kword) ? post.kword : '';
        }
        if ((!cmnFn.empty(budget_from) && !cmnFn.empty(budget_to)) && budget_from > 0) {
            cond.filters += ' AND min_charge: ' + budget_from + ' TO ' + budget_to;
        }
        if (!cmnFn.empty(day_preference)) {
            cond.filters += ' AND day_preference:"' + day_preference + '"';
        }
        if (!cmnFn.empty(time_preference)) {
            cond.filters += ' AND time_preference:"' + time_preference + '"';
        }
        if (!cmnFn.empty(start_date) && (new Date(start_date)).getTime() > 0) {
            cond.filters += ' AND start_date:"' + start_date + '"';
        }

这里我设置了 aroundLatLng 来获取距离最近的数据

 /*
  Do not fogot one thing, before using geo search, your records must have _geoloc key having following format
    "_geoloc": {
     "lat": 40.639751,
     "lng": -73.778925
    }

 */
        // Around geo search by given lat lng
        if (!cmnFn.empty(aroundLatLng) && !cmnFn.empty(aroundLatLng.lat)) {
            cond.aroundLatLng = aroundLatLng.lat + ', ' + aroundLatLng.lng;
            if (!cmnFn.empty(aroundRadius) && cond.aroundRadius > 0) {
                cond.aroundRadius = aroundRadius;
            }
        }



        // total number of searched record
        if (!cmnFn.empty(hitsPerPage)) {
            cond.hitsPerPage = hitsPerPage;
        }

        // Record starting position
        if (!cmnFn.empty(offset)) {
            cond.offset = offset;
        }

        // Page Limitation
        if (!cmnFn.empty(length)) {
            cond.length = length;
        }

        // Don't show attributesToHighlight in result set
        cond.attributesToHighlight = false;
        /* 
            restrictSearchableAttributes: List of object key, where to search in given list defined in searchableAttributes
        */
        cond.restrictSearchableAttributes = [
            'user_id',
            'title',
            'description',
            '_geoloc'
        ];
        /* 
            It will return raning info of result when search come under geo search
            Following output will return
            "_rankingInfo": {
                "nbTypos": 0,
                "firstMatchedWord": 0,
                "proximityDistance": 0,
                "userScore": 31,
                "geoDistance": 9, // Calculated distance between data geolocation given in _geoloc and search criteria in aroundLatLng
                "geoPrecision": 1,
                "nbExactWords": 0,
                "words": 1,
                "filters": 0,
                "matchedGeoLocation": {
                    "lat": 28.5503,
                    "lng": 77.2501,
                    "distance": 9
                }
            }
        */
        cond.getRankingInfo = true;
        async.waterfall([
            function (callback) {
                job_index.setSettings({
                    'attributesForFaceting': ['user_id', 'created_mode', 'min_charge', 'day_preference', 'time_preference', 'start_date'],
                    /* 
                        searchableAttributes: List of object key , where to search
                        eg: ['title', 'description']
                        Like in sql: Where title='your searched text' AND description='your searched text'
                        _geoloc is reserved keyword of algolia which will used to search geo location
                     */
                    searchableAttributes: [
                        'title',
                        'description',
                        'user_id',
                        '_geoloc'
                    ],
                    /* 
                        attributesToRetrieve: Here you can specify list of key name which you want to retrive
                        eg: ['name','address','age']
                        Like in sql: Select name, address, age
                    */
                    attributesToRetrieve: [
                        '*'
                    ]
                }).then(() => {
                    return callback(null, 'success');
                });
            }
        ], function (err, results) {
            if (err) {
                console.log('error: ' + err);
            }
            job_index.search(cond).then(results => {
                if (results.nbHits > 0) {
                    var rows = new Array();
                    for (i in results.hits) {
                        var row = {};
                        var item = results.hits[i];
                        var user_info = {};
                        user_info = item.user_info;

                        // Get distance and calculate
                        if (!cmnFn.empty(item._rankingInfo)) {
                            item.distance = cmnFn.meterToKM(item._rankingInfo['geoDistance']);
                        } else {
                            let loc = {
                                geoLoc_1: { latitude: aroundLatLng.lat, longitude: aroundLatLng.lng },
                                geoLoc_2: { latitude: item._geoloc.lat, longitude: item._geoloc.lng }
                            }
                            cmnFn.getDistance(loc, function (distance) {
                                item.distance = distance
                            })
                        }
                        /* self.isFav({ user_id: item.user_id, job_id: item.job_id }), function (err, flag) {
                            item.is_favorite = flag;
                        }; */
                        self.isFav({ user_id: item.user_id, job_id: item.job_id }).then(function (flag) {
                            item.is_favorite = flag;
                        }, function (err) {
                            item.is_favorite = false;
                        });
                        if (cmnFn.empty(item.currency)) {
                            item.currency = "₹";
                        }
                        //Delete few key from object which does not need to send in response
                        delete item['user_info'];
                        delete item['objectID'];
                        delete item['_geoloc'];
                        delete item['_rankingInfo'];
                        row.job_info = item;
                        row.user_info = user_info;
                        rows.push(row);
                    }
                    info = { status: 1, message: util.format(lang.TOTAL_RECORD_FOUND, results.nbHits), data: rows };
                    cmnFn.showMsg(res, info);
                } else {
                    info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
                    cmnFn.showMsg(res, info);
                }
            }).catch(err => {
                console.log(err);
                info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
                cmnFn.showMsg(res, info);
            });
            //res.end('' + JSON.stringify(results));
        });
    } catch (error) {
        info = { status: 0, message: lang.RECORD_NOT_FOUND, data: null };
        cmnFn.showMsg(res, info);
    }

关于php - Algolia 地理搜索不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38841256/

相关文章:

php - 我可以在 php 中使用 javascript 正则表达式吗

PHP 和 MySQL 编码

javascript - 为什么我的href只有在我手动刷新页面后才有效?

java - Lucene 禁止了不应该出现的子句 "fuzzyfied"

php - 如何在 Opencart 中检索自定义属性?

java - 在 map 中搜索耗时过长的广度优先搜索策略

java - 如何将整个本地硬盘索引到 Apache Solr?

php - 如何以最有效的方式使用通配符?

python - 在 Python 中索引 CSV 文件内容

mySQL LIKE 全文查询