Skip to content

Instantly share code, notes, and snippets.

@insekticid
Created July 24, 2020 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insekticid/452fc7e5619d3a2dff2d9c6d924c50b9 to your computer and use it in GitHub Desktop.
Save insekticid/452fc7e5619d3a2dff2d9c6d924c50b9 to your computer and use it in GitHub Desktop.
import sitemapModule from 'sitemap';
import axios from 'axios';
const { buildSitemapIndex, createSitemapsAndIndex } = sitemapModule;
let elasticsearch = axios.create({
baseURL: 'http://' + process.env.ELASTIC_SERVER + ':' + process.env.ELASTIC_PORT,
responseType: 'json'
});
elasticsearch.interceptors.request.use(request => {
//console.log('Starting Request', request)
return request
})
elasticsearch.interceptors.response.use(response => {
//console.log('Response:', response)
return response
})
let elasticData = (field) => {
return {
"_source": {
"includes": [ "name", "url" ]
},
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": field,
"size": 500000
}
}
}
}
}
const sitemapPaths = [];
let createIndex = (urls) => createSitemapsAndIndex({
urls: urls,
lastmod: new Date().toISOString(),
targetFolder: 'sitemap-search',
hostname: process.env.SITEMAP_URL,
cacheTime: 600,
sitemapName: 'sitemap',
sitemapSize: 10000, // number of urls to allow in each sitemap
gzip: true, // whether to gzip the files
})
let prepareUrl = (bucket) => {
sitemapPaths.push( { url: process.env.SITEMAP_KEY_URL + bucket.key });
}
let getData = async() => {
await elasticsearch.post(process.env.ELASTIC_INDEX + '/_search', elasticData('name.keyword'))
.then(async response =>
{
let buckets = response.data.aggregations.group_by_state.buckets;
await Promise.all(buckets.map(prepareUrl));
console.log('done keyword', buckets.length, sitemapPaths.length)
})
await elasticsearch.post(process.env.ELASTIC_INDEX + '/_search', elasticData('name.analyzed'))
.then(async response =>
{
let buckets = response.data.aggregations.group_by_state.buckets;
await Promise.all(buckets.map(prepareUrl));
console.log('done analyzed', buckets.length, sitemapPaths.length)
})
await createIndex(sitemapPaths);
console.log('done all', sitemapPaths.length)
}
getData()
@insekticid
Copy link
Author

insekticid commented Jul 24, 2020

<?php

declare(strict_types=1);

/*
 * This file is part of Recepty.eu project
 * (c) Exploit.cz <insekticid@exploit.cz>
 * (c) Recepty.eu <info@recepty.eu>
 *
 * This source file is subject to the proprietary license.
 */

namespace App\Repository;

use App\Entity\Category;

use Elastica\Query;
use Elastica\Query\BoolQuery;
use Elastica\Query\Match;
use Elastica\Query\Terms;
use FOS\ElasticaBundle\Repository;

class SearchRepository extends Repository
{
    use PagingTrait;

    public function search(string $searchTerm, ?Category $category = null, int $page = 1, int $limit = 48) : ?array
    {
        if ($searchTerm) {
            $boolQuery = $this->baseQuery($searchTerm, $category);

            $query = Query::create($boolQuery);
            $query->setParam('indices_boost', [['recipe' => 1.8]]);

            $items = $this->findPaginated($query);
            $items->setMaxPerPage($limit);
            $items->setCurrentPage($page);

            return ['items' => $items, 'searchTerm' => $searchTerm];
        }

        return null;
    }

    protected function baseQuery(string $searchTerm, ?Category $category = null) : BoolQuery
    {
        $boolQuery = new BoolQuery();

        $fieldQuery = new Match();
        $fieldQuery->setFieldQuery('name', $searchTerm);
        $fieldQuery->setFieldFuzziness('name', 1);
        $boolQuery->addShould($fieldQuery);

        if ($category) {
            $categoryQuery = new Terms();
            $categoryQuery->setTerms('category', [$category->getId()]);
            $boolQuery->addMust($categoryQuery);
        }

        return $boolQuery;
    }
}
<?php

declare(strict_types=1);

/*
 * This file is part of Recepty.eu project
 * (c) Exploit.cz <insekticid@exploit.cz>
 * (c) Recepty.eu <info@recepty.eu>
 *
 * This source file is subject to the proprietary license.
 */

namespace App\Repository;

use App\Util\LimitedPagerfanta;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;

trait PagingTrait
{
    protected function createPaginator(Query $query, int $limit, int $page, ?int $limitedPageNumber = null) : Pagerfanta
    {
        $adapter = new DoctrineORMAdapter($query);

        if ($limitedPageNumber) {
            $pager = new LimitedPagerfanta($adapter);
            $pager->setLimitedPageNumber($limitedPageNumber);
        } else {
            $pager = new Pagerfanta($adapter);
        }

        $pager->setMaxPerPage($limit);
        $pager->setCurrentPage($page);

        return $pager;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment