Working with JSON arrays and objects in PHP
The client has some confusing resources around JSON arrays and objects, and how to specify them in PHP. In particular, the problem is caused by empty objects and empty arrays. This article tells you some common patterns in the Elasticsearch JSON API and how to convert them into PHP representations.
Empty Object
The Elasticsearch API uses empty JSON objects in many places, which can cause problems in PHP. Unlike other languages, PHP does not provide a "short" indication of empty objects, so many developers do not know how to make an empty object.
Consider adding highlighting to your query:
- {
- "Query": {
- "Match": {
- " content": "quick brown fox"
- }
- },
- "Highlight": {
- "Fields": {
- "Content": {}//This empty object is the place that caused the problem
- }
- }
- }
The problem is that PHP automatically transforms "content" : {} into "content" : [], which is no longer valid for Elasticsearch DSLs. We need to tell PHP that an empty object is an object that is explicitly tried, not an array. If you want to define a query in PHP, you need to do this:
- $params [' body '] = Array (
- ' query ' = = Array (
- ' match ' = = Array (
- ' content ' = ' quick brown fox '
- )
- ),
- ' Highlight ' = Array (
- ' fields ' = = Array (
- ' content ' = (object) Array ()//We throw an empty array onto an object to represent an empty object, and JSON is now able to encode the correct
- )
- )
- );
- $results = $client->search ($params);
By using an empty array to convert to an object, we can force the Json_encode parser to properly output an empty object instead of an empty array. Sadly, this lengthy solution is the only one in PHP that can achieve the goal. Because PHP does not provide a "short" indication for empty objects.
Array Object
Another common pattern in the Elasticsearch DSL is an array object, for example, consider adding a sort to the query:
- {
- "Query": {
- "Match": { "content": "Quick brown Fox"}
- },
- "Sort": [ //"Sort" contains a JSON array object
- {"Time": {"order": "desc"}},
- {"popularity": {"order": "desc"}}
- ]
- }
This arrangement is very common, but in PHP it can be tricky to think that she needs a nested array, PHP's lengthy and difficult solution continues, in order to construct an array object, you do need an array of arrays:
- $params [' body '] = Array (
- ' query ' = = Array (
- ' match ' = = Array (
- ' content ' = ' quick brown fox '
- )
- ),
- ' sort ' = = array ( //This array is encoded as "sort": []
- Array (' time ' = = array (' order ' = ' desc ') '), //This array is encoded as {"time": {"order": "Desc"}}
- Array ('popularity ' = = Array (' order ' = ' desc ')) //This array is encoded as {"popularity": {"order": "desc "}}
- )
- );
- $results = $client->search ($params);
If you are using the php5.4+ version, I strongly encourage you to use the short array syntax, which makes these nested arrays easier to read:
- $params [' body '] = [
- ' query ' = [
- ' Match ' = [
- ' content ' = ' quick brown fox '
- ]
- ],
- ' sort ' = [
- [' time' = [' order ' = ' desc ']],
- ['popularity ' = [' order ' = ' desc ']]
- ]
- ];
- $results = $client->search ($params);
Empty Array Object
Occasionally, you will encounter the need for the previous two modes, the integral query function is a good example, sometimes requires an array object, these objects may be empty JSON objects.
This query is given below:
- {
- "Query": {
- "Function_score": {
- "Functions": [
- {
- "Random_score": {}
- }
- ],
- "Boost_mode":"replace"
- }
- }
- }
We can use the following PHP code to generate:
- $params [' body '] = Array (
- ' query ' = = Array (
- ' function_score ' = Array (
- ' functions ' = = Array ( //This code: "Functions": []
- Array ( //This is encoded into an object in an array: {"Random_score": {}}
- ' random_score ' = (object) Array () //This is encoded into an empty JSON object: "Random_score": {}
- )
- )
- )
- )
- );
- $results = $client->search ($params);
elasticsearch-php working with JSON arrays and objects