Skip to content

Commit

Permalink
Merge pull request solariumphp#477 from solariumphp/develop
Browse files Browse the repository at this point in the history
Merging develop to master for new release
  • Loading branch information
basdenooijer authored Jan 31, 2017
2 parents a2a87dd + 8d25cfb commit 06e957a
Show file tree
Hide file tree
Showing 14 changed files with 1,180 additions and 75 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# CHANGELOG

## 3.8.0 - 2017-01-31

- bugfix: use GET request for extracting remote files
- added: support for simple group format in response parser
- added: helper for fetching ValueGroup from a Grouped result
- bugfix: prevent ParallelExecution Curl spinloop
- added: Guzzle 3 and Guzzle 6 client adapters
- improvement: various fixes in documentation

## 3.7.0 - 2016-10-28

- added: support for nested documents in update query
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"phpunit/phpunit": "~3.7",
"squizlabs/php_codesniffer": "~1.4",
"zendframework/zendframework1": "~1.12",
"satooshi/php-coveralls": "~1.0"
"satooshi/php-coveralls": "~1.0",
"guzzlehttp/guzzle": "^3.8 || ^6.2"
},
"suggest": {
"minimalcode/search": "Query builder compatible with Solarium, allows simplified solr-query handling"
Expand Down
8 changes: 4 additions & 4 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Solarium offers a plugin system to allow for easy extension by users. But plugin
BufferedAdd plugin
==================

When you need to do a lot of document inserts or updates, for instance a bulk update or initial indexing, it’s most efficient to do this in batches. This makes a lot more difference than you might think, for some benchmarks see [http://www.raspberry.nl/2011/04/08/solr-update-performance/ this blogpost](http://www.raspberry.nl/2011/04/08/solr-update-performance/_this_blogpost "wikilink").
When you need to do a lot of document inserts or updates, for instance a bulk update or initial indexing, it’s most efficient to do this in batches. This makes a lot more difference than you might think, for some benchmarks see [this_blog post](http://www.raspberry.nl/2011/04/08/solr-update-performance/).

This can be done very easily with this plugin, you can simply keep feeding documents, it will automatically create batch update queries for you.

Expand Down Expand Up @@ -250,7 +250,7 @@ Some important notes:
2. Rows and start (paging and offset) still work, but again this is not adjusted for filtering. So if you sets rows to 10, you might get less because of the filtering.
3. While it's not strictly necessary, you should sort by score as this is much more efficient. This also fits with the expected use case of getting only the best scoring documents.
4. Result document marking is done using a decorator, so you should still be able to use a custom document class.
5. Be aware of the issues related to 'normalizing' scores: [http://wiki.apache.org/lucene-java/ScoresAsPercentages more info](http://wiki.apache.org/lucene-java/ScoresAsPercentages_more_info "wikilink"). This filter only uses score to calculate a the relevancy relative to the best result and doesn't return this calculated score, but be sure to test your results! In cases like an autocomplete or 'best-bet' type of search this filter can be very useful.
5. Be aware of the issues related to 'normalizing' scores [more info](http://wiki.apache.org/lucene-java/ScoresAsPercentages). This filter only uses score to calculate a the relevancy relative to the best result and doesn't return this calculated score, but be sure to test your results! In cases like an autocomplete or 'best-bet' type of search this filter can be very useful.

Example usage
-------------
Expand Down Expand Up @@ -319,7 +319,7 @@ Some important notes:
- The execution time is limited by the slowest request. If you execute 3 queries with timings of 0.2, 0.4 and 1.2 seconds the execution time for all will be (near) 1.2 seconds.
- If one of the requests fails the other requests will still be executed and the results parsed. In the result array the entry for the failed query will contain an exception instead of a result object. It’s your own responsibility to check the result type.
- All query types are supported, and you can even mix query types in the same execute call.
- For testing this plugin you can use a special Solr delay component I’ve created (and used to develop the plugin). For more info see [http://www.raspberry.nl/2012/01/04/solr-delay-component/ this blog post](http://www.raspberry.nl/2012/01/04/solr-delay-component/_this_blog_post "wikilink").
- For testing this plugin you can use a special Solr delay component I’ve created (and used to develop the plugin). For more info see [this blog post](http://www.raspberry.nl/2012/01/04/solr-delay-component/).
- Add queries using the addQuery method. Supply at least a key and a query instance. Optionally you can supply a client instance as third argument. This can be used to execute queries on different cores or even servers. If omitted the plugin will use it's own client instance.

Example usage
Expand Down Expand Up @@ -486,4 +486,4 @@ foreach ($prefetch as $document) {

htmlFooter();

```
```
2 changes: 1 addition & 1 deletion docs/queries/realtimeget-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ See the example code below.
Executing a RealtimeGet query
-----------------------------

First of all create a RealtimeGet query instance and set one ore multiple IDs. Use the `realtimeGet` method of the client to execute the query object.
First of all create a RealtimeGet query instance and set a single ID or multiple IDs. Use the `realtimeGet` method of the client to execute the query object.

See the example code below.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ Examples

These are two examples of update query usages. See the following sections for the details and examples of all available commands.

Add documents: ```php
Add documents:

```php
<?php

require(__DIR__.'/init.php');
Expand Down Expand Up @@ -68,7 +70,9 @@ htmlFooter();

```

Delete by query: ```php
Delete by query:

```php
<?php

require(__DIR__.'/init.php');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ This command commits any buffered commands to the index. This buffering is done

If you use the autoCommit feature on the Solr core you probably don't want to use the commit command, because that would trigger a commit in between the autoCommit interval. In all other cases it makes sense to add a commit to your update (or at least to the last update request if you issue multiple) to apply your update to the Solr index.

This command command starts the commit process on the server, bit the actual commit process might take a while. If your update command with a commit returns successfully this only means Solr received the commands and is processing them, the result might not be visible for a while. The time this takes depends on many factors: hardware, index size, number of index segments, the commands to execute, the search load, etcetera. It can vary between milliseconds and minutes.
This command starts the commit process on the server, bit the actual commit process might take a while. If your update command with a commit returns successfully this only means Solr received the commands and is processing them, the result might not be visible for a while. The time this takes depends on many factors: hardware, index size, number of index segments, the commands to execute, the search load, etcetera. It can vary between milliseconds and minutes.

Options
-------
Expand Down
174 changes: 174 additions & 0 deletions library/Solarium/Core/Client/Adapter/Guzzle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
* * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <[email protected]>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
*
* @link http://www.solarium-project.org/
*/

namespace Solarium\Core\Client\Adapter;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\RequestOptions;
use Solarium\Core\Configurable;
use Solarium\Core\Client\Request;
use Solarium\Core\Client\Response;
use Solarium\Core\Client\Endpoint;
use Solarium\Exception\HttpException;

/**
* Guzzle HTTP adapter.
*/
class Guzzle extends Configurable implements AdapterInterface
{
/**
* The Guzzle HTTP client instance.
*
* @var GuzzleClient
*/
private $guzzleClient;

/**
* Execute a Solr request using the cURL Http.
*
* @param Request $request The incoming Solr request.
* @param Endpoint $endpoint The configured Solr endpoint.
*
* @return Response
*
* @throws HttpException Thrown if solr request connot be made.
*
* @codingStandardsIgnoreStart AdapterInterface does not declare type-hints
*/
public function execute($request, $endpoint)
{
//@codingStandardsIgnoreEnd
$requestOptions = [
RequestOptions::HEADERS => $this->getRequestHeaders($request),
RequestOptions::BODY => $this->getRequestBody($request),
RequestOptions::TIMEOUT => $endpoint->getTimeout(),
];

// Try endpoint authentication first, fallback to request for backwards compatibility
$authData = $endpoint->getAuthentication();
if (empty($authData['username'])) {
$authData = $request->getAuthentication();
}

if (!empty($authData['username']) && !empty($authData['password'])) {
$requestOptions[RequestOptions::AUTH] = [$authData['username'], $authData['password']];
}

try {
$guzzleResponse = $this->getGuzzleClient()->request(
$request->getMethod(),
$endpoint->getBaseUri() . $request->getUri(),
$requestOptions
);

$responseHeaders = [
"HTTP/{$guzzleResponse->getProtocolVersion()} {$guzzleResponse->getStatusCode()} "
. $guzzleResponse->getReasonPhrase(),
];

foreach ($guzzleResponse->getHeaders() as $key => $value) {
$responseHeaders[] = "{$key}: " . implode(', ', $value);
}

return new Response((string)$guzzleResponse->getBody(), $responseHeaders);
} catch (\GuzzleHttp\Exception\RequestException $e) {
$error = $e->getMessage();
throw new HttpException("HTTP request failed, {$error}");
}
}

/**
* Gets the Guzzle HTTP client instance.
*
* @return GuzzleClient
*/
public function getGuzzleClient()
{
if ($this->guzzleClient === null) {
$this->guzzleClient = new GuzzleClient($this->options);
}

return $this->guzzleClient;
}

/**
* Helper method to create a request body suitable for a guzzle 3 request.
*
* @param Request $request The incoming solarium request.
*
* @return null|resource|string
*/
private function getRequestBody(Request $request)
{
if ($request->getMethod() !== Request::METHOD_POST) {
return null;
}

if ($request->getFileUpload()) {
return fopen($request->getFileUpload(), 'r');
}

return $request->getRawData();
}

/**
* Helper method to extract headers from the incoming solarium request and put them in a format
* suitable for a guzzle 3 request.
*
* @param Request $request The incoming solarium request.
*
* @return array
*/
private function getRequestHeaders(Request $request)
{
$headers = [];
foreach ($request->getHeaders() as $headerLine) {
list($header, $value) = explode(':', $headerLine);
if ($header = trim($header)) {
$headers[$header] = trim($value);
}
}

if (!isset($headers['Content-Type'])) {
if ($request->getMethod() == Request::METHOD_GET) {
$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
} else {
$headers['Content-Type'] = 'application/xml; charset=utf-8';
}
}

return $headers;
}
}
Loading

0 comments on commit 06e957a

Please sign in to comment.