floriansemm / SolrBundle

Solr-Integration into Symfony and Doctrine2
http://floriansemm.github.io/SolrBundle
MIT License
123 stars 73 forks source link

Using without ORM #164

Open vladislavs1321 opened 7 years ago

vladislavs1321 commented 7 years ago

Hello, is it possible to use this bundle without Doctrine, and use simple class with annotation for mapping, coz data already exist in solr and handled without any ORM? i want to use query builder, but don't want to duplicate data in mysql.

floriansemm commented 7 years ago

Yes it is. You have to consider two things:

  1. the document must be placed in a valid entity-mapping directory
  2. you must set the hydration-mode to index

Example document:

namespace Acme\DemoBundle\Entity;

use FS\SolrBundle\Doctrine\Annotation as Solr;

/**
 * @Solr\Document(index="core0")
 */
class IndexOnlyDocument
{
    /**
     * @Solr\Id(generateId=true)
     */
    protected $id;

    /**
     * @Solr\Field(type="string")
     */
    protected $name;
}

Querybuilder

    $query = $this->get('solr.client')->getQueryBuilder(IndexOnlyDocument::class)
        ->where('name_s')->is('1230000')
        ->getQuery();
    $query->setHydrationMode(HydrationModes::HYDRATE_INDEX);

    $result = $query->getResult();
vladislavs1321 commented 7 years ago

This is my example query

omitHeader=true
wt=json
json.nl=flat
q=name_s:Motorhacken
start=0
rows=1000000
fl=
fq=id:document_*

and there is question about fields naming, i have name in solr instead of name_s; and there is another question how to make query, if i have field id like a string ?


{
        "id":"node_group_g482_de",
        "master_id":"node_group_g482",
        "remote_id":"g482",
        "type":"group",
        "lang":"de",
        "availableForMarket":["all"],
        "name":"Motorhacken"
       ...
}
floriansemm commented 7 years ago

Your entity/model would look like this

/**
 * @Solr\Document()
 */
class TestDocument
{
    /**
     * @Solr\Id()
     */
    protected $id;

    /**
     * @Solr\Field()
     */
    protected $name;
}

You can filter for Id like this:

$query = $this->get('solr.client')->getQueryBuilder(TestDocument::class)
    ->where('id')->is('node_group_g482_de')
    ->getQuery();
$query->setHydrationMode(HydrationModes::HYDRATE_INDEX);
$result = $query->getResult();
vladislavs1321 commented 7 years ago

problem that in query by 'name' property i have additional fq=id:document*, but my id field have no prefix 'document'

floriansemm commented 7 years ago

Yes thats true. I have to revert my answer. It is only possible with hacks to query your index. But can can still use the solarium API to get results.

vladislavs1321 commented 7 years ago

Yep, but qb functionality so sweet. is it possible to add inside annotation parameter name, like in doctrine, to connect it with already exists fields in solr?

floriansemm commented 7 years ago

No. The problem is not your field-mapping, is how the bundle filters documents for a given entity/model query.

vladislavs1321 commented 7 years ago

But does it make sense to handle this situation with bundle(make fork?) of try to switch to some custom solution? What is your advice?

floriansemm commented 7 years ago

It think it is not necessary to fork this bundle. You have to overwrite the behavior in https://github.com/floriansemm/SolrBundle/blob/1.6.x/Query/SolrQuery.php#L174. This means you need a new Query class and QueryBuilder::getQuery() must return your custom query class.

puku commented 5 years ago

I've faced the same problem. After I've updated this bundle from the 1.5 version to 1.6, my application stopped to response correct data, because of this filter. So maybe it would be really better to add an opportunity for customization of this filter? For example: add DocumentKeyProvider, which by default will work as it's now and which can be overridden using annotations Id(provider=CustomKeyProvider) (it's just first idea came in my head). If you think that it makes sense, I can work on this pull request.