Saya menggunakan FOSElasticaBundle dengan Symfony 3. Saya ingin mencari di indeks yang berbeda di ES6.
Saya memiliki 2 entitas Anjing, Kucing dengan nama bidang "pemilik" (entitas Pengguna). Anjing dan Kucing memiliki bidang "nama" (string), saya ingin mencari setiap Anjing dan hanya Kucing yang pemiliknya ditetapkan di userId.
Contoh:
- Pengguna: #1 Bob
- Pengguna: #2 Charle
- Kucing: #1 Ruf, pemilik #1
- Kucing: #2 Pat, pemilik #2
- Anjing: #1 Rufu
- Anjing: #2 Pat
Jika saya Bob, dan saya menulis "Ruf". Saya ingin hasilnya Cat#1, Dog#1 tetapi jika saya menulis "Pat", saya ingin hasilnya Anjing#2.
Elastica.yml
fos_elastica:
clients:
default:
host: %elastic_host%
port: %elastic_port%
indexes:
dog:
finder: ~
client: default
types:
dog:
indexable_callback: 'getEnabled'
properties:
id:
type: integer
name: ~
persistence:
driver: orm
model: AppBundle\Entity\Dog
finder: ~
elastica_to_model_transformer:
ignore_missing: true
cat:
finder: ~
client: default
types:
cat:
indexable_callback: 'getEnabled'
properties:
name: ~
owner:
type: "object"
properties:
id: integer
persistence:
driver: orm
model: AppBundle\Entity\Cat
finder: ~
elastica_to_model_transformer:
ignore_missing: true
Saya mencari di ES dengan metode:
public function search(User $user, $query)
{
$search = $this->indexManager->getIndex('dog')->createSearch();
$search->addIndex('cat');
$search->addType('dog');
$search->addType('cat');
$resultSet = $search->search($query);
return $this->formatResult($resultSet);
}
Bagaimana saya bisa melakukan pencarian saya? Haruskah saya menggunakan Filter pada Cat? Bisakah saya menggunakan satu repositori per indeks?
3 jawaban
Anda dapat mencari menggunakan beberapa indeks menggunakan ruflin/elastica. Ini akan menjadi sesuatu seperti:
$search = new Elastica\Search($client);
$search->addIndex('dog')->addIndex('cat');
try {
$searchResponse = $search->search($q);
return $searchResponse->getResults();
} catch (ResponseException $exception) {
return [];
}
Maaf, tapi saya tidak tahu bagaimana melakukan ini dengan FOSElasticaBundle.
Finder harus mencari berdasarkan semua indeks: @fos_elastica.finder.app
Hasil kueri terlihat seperti:
$boolQuery = new \Elastica\Query\BoolQuery();
/*****************DOG PART**********************/
$dogBoolQuery = new \Elastica\Query\BoolQuery();
$dogNameMatchQuery = new \Elastica\Query\Term();
$dogNameMatchQuery->setTerm('name', $query);
$dogTypeFilter = new \Elastica\Query\Type();
$dogTypeFilter->setType('dog');
$dogBoolQuery->addMust($dogNameMatchQuery);
$dogBoolQuery->addFilter($dogTypeFilter);
/***************************************/
/*****************CAT PART**********************/
$catBoolQuery = new \Elastica\Query\BoolQuery();
$catTypeFilter = new \Elastica\Query\Type();
$catTypeFilter->setType('cat');
$ownerNameTermQuery = new \Elastica\Query\Term();
$ownerNameTermQuery->setTerm('id', $user->getId());
$ownerQuery = new \Elastica\Query\HasParent($ownerNameTermQuery, 'owner');
$catBoolQuery->addFilter($catTypeFilter);
$catBoolQuery->addFilter($ownerQuery);
/***************************************/
$boolQuery->addShould($dogBoolQuery);
$boolQuery->addShould($catBoolQuery);
$searchQuery = new \Elastica\Query();
$searchQuery->setQuery($boolQuery);
$results = $this->finder->find($searchQuery);
Saya akan melakukan dua pencarian terpisah, satu untuk setiap index. Jika Anda memerlukan satu kueri untuk keperluan pagination, maka saya akan menggunakan api Elasticsearch secara langsung, karena saya tidak yakin apakah FosElasticaBundle mendukung pencarian semacam ini. Anda dapat menemukan cara melakukan pencarian beberapa indeks di Elasticsearch dokumentasi menggunakan panggilan Curl ke ES api.