Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial functional tests #1

Merged
merged 17 commits into from
Oct 24, 2017

Conversation

dkarlovi
Copy link
Contributor

@dkarlovi dkarlovi commented Oct 17, 2017

As suggested in rollerworks/search#179

@dkarlovi
Copy link
Contributor Author

@sstok is this something you had in mind?

.gitignore Outdated
@@ -1,3 +1,4 @@
/.idea/
Copy link
Member

@sstok sstok Oct 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this, you can use the global .gitignore instead 👍
https://help.github.com/articles/ignoring-files/#create-a-global-gitignore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for the link.

@sstok
Copy link
Member

sstok commented Oct 18, 2017

Thank you so much for your work so far 👍

@dkarlovi
Copy link
Contributor Author

dkarlovi commented Oct 18, 2017

@sstok can you elaborate a bit on the registerField()? How is that supposed to work exactly?

ie. how do I map from fieldset customer-name to index invoices, type invoices, property customer.full_name?

protected function configureConditionGenerator(QueryConditionGenerator $conditionGenerator)
{
// TODO: mapping field set alias to Elasticsearch property
return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sstok this is where I'm hoping you can shed some light. :)

$conditionGenerator = new QueryConditionGenerator($condition);
$this->configureConditionGenerator($conditionGenerator);

// TODO: where do I get these from?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sstok also here, don't quite understand how you imagined for it to work.

@sstok
Copy link
Member

sstok commented Oct 18, 2017

The registerField method works similar to the Doctrine DBAL/ORM implementation 😃
You should be able to map a search field to one or more fields, but ElasticSearch actually is much more advanced in this topic as (IIRC) you can create an index with combining fields.

It's a while since I worked on the ElasticSearch implementation 😅

@dkarlovi
Copy link
Contributor Author

@sstok sure, we can work on advanced mappings later, for now let's try and get anything working. :)

For example, how did you imagine we map id: 1 to /invoices/invoices, property _id with the registerField()?

@@ -15,7 +15,7 @@ return PhpCsFixer\Config::create()
'@Symfony:risky' => true,
'@PHP70Migration' => true,
'@PHP71Migration' => true,
'array_syntax' => array('syntax' => 'short'),
'array_syntax' => ['syntax' => 'short'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is ironic. 😭

@dkarlovi
Copy link
Contributor Author

@sstok I've added some changes to the query generator itself:

  1. getQuery now wraps in query so you can use it as is (refactored your tests to match)
  2. implemented a registerField in some manner and refactored the hardcoded mappings in query generator and (your tests)

Can you take a look and point out any glaring errors or do you feel this might be a way to go?

@dkarlovi
Copy link
Contributor Author

@sstok

I've taken the McDonald's principle and have made a property notation format proposition. If you have any feedback on this or anything else in this PR, I'd really love to hear it. Also need a review regarding normalizers (specifically date, but others too).

I think this has quite some potential, need to work out the details.

Copy link
Member

@sstok sstok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work so far 👍 I left some notes and idea's.
I'm away from keyboard later today. So may not be able to respond directly.

private $searchCondition;
private $fieldSet;
// private $fieldSet;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property is used in the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, my bad. :(

// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#ranges-on-dates
$values = array_values($valuesBag->getSimpleValues());
foreach ($values as $idx => $value) {
$valuesBag->removeSimpleValue($idx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note a ValuesBag is not immutable, and the QueryConditionGenerator should not change the ValuesBag.
Better to clone this.

For the future: Usually when a Query generator needs something special is to use TypeExtensions with options like elastic_search_structure_transformer which receives the ValuesBag (or ValuesGroup, or both) and allows to change it's structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you write/link an example? How do I register transformers per type (say, always transform Date like this, no matter where it is)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just working on this and it's annoying as it is, especially since it's only placeholder code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foreach ($valuesBag->get(Range::class) as $range) {
$ids = array_merge($ids, range($range->getLower(), $range->getUpper()));
}
if (false === empty($ids)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the explicit Boolean check, you can simple use if (f!empty($ids)) {
Same goes for all other code occurrences.


$bool[$includingType][] = [$this->mappings[$fieldName]->indexName => $rangeParams];
}
if (false === $isId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check needs to be done sooner as simple values can also apply to the id, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll be moving the whole thing.

return $converter->convertValue($value);
}

/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This phpdoc is useless, with private methods we only use it when it not directly clear what the method does or when there are some special rules/conventions. And thanks to strict types we don't need it here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I'm not a big fan of the selective decision process if a docblock is necessary. It puts burden on the developer / reviewer to figure out. My path usually is to add them everywhere, it doesn't hurt readability, but it does allow for my tooling to work better.

I'll remove it here, obviously. 👍

namespace Rollerworks\Component\Search\Elasticsearch;

/**
* Interface ValueConversion.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please try to use a better description here. And don't forget to add an author tag 👍 your doing a great job here 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I think I have a good idea how we can push the functionality further. Basically, special cases can go to the per-type extension which should allow, for example, exceptions for dates and IDs while keeping the basic query generator quite simple.

It'll be probably done monday. How do you plan actually implementing the client, if not using Elastica?

@dkarlovi
Copy link
Contributor Author

Added a query conversion concept (which should handle special cases for IDs, dates, etc).

Also, you've inverted less than / greater than in your code and tests, I had a WTF moment there for a bit. 😭 Check the latest changes and feedback if you get the chance.

BTW how do I explain to the system that any date-y field should be converted by my DateConverter? Currently, BirthdayType is broken as it's not handled.

Dalibor Karlović added 2 commits October 23, 2017 14:58
@dkarlovi
Copy link
Contributor Author

dkarlovi commented Oct 23, 2017

I've added support for nested queries (for example, binding property items[].label will do a nested query on items and do a regular query on items.label), will finish compare and matchers tomorrow.

What can we do to get this merged and released tomorrow? I'd like to include a preview version of this in my app ASAP (that's the reason I've done this work in the first place). If you could help me out here, it would be great. For example, start by submitting the package to Packagist so I can add my fork to my app.

Thanks.

@sstok
Copy link
Member

sstok commented Oct 24, 2017

Amazing work! This looks good enough to move forwards.

About the Client part, I didn't want to force a specific client implementation to use the user.
For Elastica we can pass the generated query to https://github.com/ruflin/Elastica/blob/master/lib/Elastica/Query.php 👍

For the API-Platform we need a full integration (using Elastica) to also make the mapping of Resources to Indexes/Documents work. But I'm not sure what the best approach is for this.
For limiting access we need to have some Context Listener that will (based on a custom implementation) ensures the the ElasticSearch query limits the results to what's accessible by the user.

@dkarlovi
Copy link
Contributor Author

Amazing work! This looks good enough to move forwards.

\o/ Could you submit the package to Packagist, it would allow us to move forward on this.

For the API-Platform we need a full integration (using Elastica) to also make the mapping of Resources to Indexes/Documents work. But I'm not sure what the best approach is for this.

Maybe require FOS Elastica Bundle and compiler-pass the mapping into it?

@sstok
Copy link
Member

sstok commented Oct 24, 2017

I'm going to merge this one so we can move forward 👍

@sstok sstok merged commit ee51264 into rollerworks:implementation Oct 24, 2017
@sstok
Copy link
Member

sstok commented Oct 24, 2017

Thank you @dkarlovi

@dkarlovi
Copy link
Contributor Author

Wait, I'm pushing more stuff!

@dkarlovi
Copy link
Contributor Author

OK, opening a new PR. :)

@dkarlovi dkarlovi mentioned this pull request Oct 24, 2017
@sstok
Copy link
Member

sstok commented Oct 24, 2017

No problem ;) I can even give you push access to this repository as you did an amazing job and I don't have always time to review everything in detail 😄

Basically I have a few rules (I still need to formalize these):

  • Don't use the GitHub UI for making direct commits (except for fixing small typo's) - Use pull requests with clear commit messages and use Git rebase (don't merge) for updating your local branch, be sure to clean-up any WIP commits afterwards (I didn't do this for this pull request as it would be to much work with set-up of the master branch and all).

  • Use https://github.com/park-manager/hubkit for merging pull-requests and making releases (no major releases yet!!)

  • Don't make a make major release (everything for RollerworksSearch v2 is still in alpha atm). Feel free to make unstable 0.x minor/patch releases (using Hubkit), note that you need to have git signing enabled for this.

When in doubt about something feel free to ask me 👍 (I will always do a review afterwards)
Again thank you every much for your amazing work and trust in RollerworksSearch 😸

@dkarlovi
Copy link
Contributor Author

I can even give you push access to this repository

As said before, I really think you should consider a mono-repo for this project, the overhead of setup required for every single-repo will be quite high. Not that I'm requesting push access for that mono repo. :)

For example, I like to setup all the infra stuff to be run from a Makefile and then can just run make before commiting.

clear commit messages

That's why I'd rather you undo this merge as I've been doing WIP commits which I intended to fix afterward.

sstok added a commit that referenced this pull request Oct 25, 2017
This PR was merged into the 1.0-dev branch.

Discussion
----------

Missed in #1.

Commits
-------

a1d74a3 WIP pattern matcher support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants