Given in the end of the question is an terminal command showing a simple Elasticsearch mapping. I need to set up this kind of mapping for an index using Elasticsearch-PHP. And I need to do this at the time when I am indexing the data.
I know how to index in Elasticsearch-PHP. It will be something like
for($i = 0; $i < 100; $i++) {
$params['body'][] = [
'index' => [
'_index' => 'my_index',
'_type' => 'my_type',
]
];
$params['body'][] = [
'my_field' => 'my_value',
'second_field' => 'some more values'
];
}
$responses = $client->bulk($params);
My question is that how will I set up a Mapping, corresponding to the particular Mapping given below in the elasticsearch-PHP format (I believe it will become an associative array, but I am not sure of further details)?
This is the example ES Mapping, that I want to convert to the format used in PHP:
PUT _template/packets
{
"template": "packets-*",
"mappings": {
"pcap_file": {
"dynamic": "false",
"properties": {
"timestamp": {
"type": "date"
},
"layers": {
"properties": {
"ip": {
"properties": {
"ip_ip_src": {
"type": "ip"
},
"ip_ip_dst": {
"type": "ip"
}
}
}
}
}
}
}
}
}
If you don't update your mapping - you don't have to put mapping each time you re-index data into elasticsearch. But if you do, of you create index with new name you can do this:
$put = [
'mappings' => [
// your mapping here
],
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://yourHost:9200/yourIndex');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($put));
curl_exec($ch);
or you can use elasticsearch package:
$params = [
'index' => 'yourIndex',
'body' => [
'mappings' => [
// your mapping here
]
]
];
$response = $client->indices()->create($params);
Related
i have a problem with elasticsearch
when i send request for add nested object with elasticseach script in postman it work but when i wanna send request for add new object in elasticseach , All objects in my index disappear.
it not work , this eliminates all other objects in elasticsearch and only add itself:
$params = [
'script' => [
'source' => 'ctx._source.products.add(params.products)',
'lang'=>'painless',
'params' =>['id'=>1,'name'=>'john']
]
];
$http = new Client();
$result = $http->request('post','http://my_server/new_frotel/_update/123', [
'body' =>$params,
'headers'=>[
'content-type'=>'application/json'
]
])
but it work in postman
POST : http://my_server/new_frotel/_update/123
{
"script": {
"source": "ctx._source.products.add(params.products)",
"lang": "painless",
"params": {
"products": {
"id":1,
"name":"john"
}
}
}
}
Sorry for the bad title, but I don't know how to create following JSON in PHP:
{
"id":"1",
"method":"getData",
"params":{
"options":{
"element":{
"id":"1a_ext",
"type":1,
"keyType":"externalkey"
},
"moreInfo":true,
"userFields":[
"id",
"name",
"longname",
"externalkey"
]
}
},
"jsonrpc":"2.0"
}
I don't know to do the part after "params" (how do I "put" options "into" params) - for the other parts I know what I have to do:
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
$json = json_encode($json, true);
return self::request($json);
}
I would really appreciate your help, thanks!
You directly can assign to the params keys like
$json['params']['options'] = $your_options;
Full version of your code as an example
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
# add something to param index
$json['params']['options'] = $your_options;
$json = json_encode($json, true);
return self::request($json);
}
You can create the this in array format in PHP and then JSON encode:
$arr = [
'id' => 1,
'method' => 'getData',
'params' => [
'options' => [
'element' => [
'id' => '1a_ext',
'type' => 1,
'keyType' => 'externalKey'
],
'moreInfo' => true,
'userFields' => [
'id',
'name',
'longname',
'externalKey'
]
]
],
'jsonrpc' => '2.0'
];
$json = json_encode($arr);
Instead of spoonfeeding, i would like to help related, Whenever if you find difficulties to create an array representation of a JSON then you should use var_export(array, true) the second parameter must be true to return the variable representation instead of outputting it
<?php
$json_str = '{
"id": "1",
"method": "getData",
"params": {
"options": {
"element": {"id": "1a_ext", "type": 1, "keyType": "externalkey"},
"moreInfo": true,
"userFields": ["id", "name", "longname", "externalkey"]
}
},
"jsonrpc": "2.0"
}';
$json_arr = var_export(json_decode($json_str, true), true);
print_r($json_arr);
check the output here https://paiza.io/projects/eUZZDsTsSFSM4m9WMl05Ow
$json_arr is an array representation for your JSON, now you can dynamic the array values
ElasticSearch tokenizes the data.
So "this-that" gets split into 2 tokens.
If it makes a difference, I am using the 6.6 version of ES.
I have documents, that have different fields, such as title, descriptions, name, etc.
In order for us to have a unique identifier, the text in Title "This that" get slugified into "this-that".
I am trying to to query for "this-that" that would return that one document.
I have tried all sorts of things. I tried suggestions from other questions in this forum, as well as instructions in the https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer.html page.
Unfortunately, nothing seems to work.
Your help would be greatly appreciated.
Thank you in advance.
https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer.html
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$hosts = ['localhost:9200'];
$client = ClientBuilder::create()
->setHosts($hosts)
->build();
$params = array();
$params = [
'index' => 'shows',
'type' => '_doc',
'body' => [
'size'=> 10000,
'query' => [
'bool' => [
'must' => [ 'match' => [ 'name' => 'this-that'] ],
]
]
]
];
$response = $client->search($params);
print_r($response);
?>
There are no errors, but it finds all instances with the word "this" and the word "that" in the name field.
I would like to get just the one document back!
You can experiment with analyzers and tokenizers using Kibana console or http:
curl -XPOST "http://localhost:9200/_analyze" -H 'Content-Type: application/json' -d'{ "analyzer": "standard", "text": "this-that"}'
{
"tokens" : [
{
"token" : "this",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "that",
"start_offset" : 5,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 1
}
]
}
curl -XPOST "http://localhost:9200/_analyze" -H 'Content-Type: application/json' -d'{ "analyzer": "keyword", "text": "this-that"}'
{
"tokens" : [
{
"token" : "this-that",
"start_offset" : 0,
"end_offset" : 9,
"type" : "word",
"position" : 0
}
]
}
To have always exact match for field, you must use keyword-tokenization. You can do it like this:
PUT test-index
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "keyword"
}
}
}
}
Which is exactly same as defining field as a keyword type to begin with:
PUT test-index2
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
I can't figure out how unit testing works.
I have controller which returns a JSON response
Controller.php
public function getDiscount(Request $request)
{
if (isset($request) && !empty($request)) {
return response()->json($this->discount->calculateDiscount($request->json()->all()))->getOriginalContent();
}
}
With postman, this is the result of this route:
Post by client:
{
"customer-id": "3",
"items": [
{
"product-id": "A101",
"quantity": "2",
"unit-price": "9.75",
"total": "19.50"
},
{
"product-id": "A102",
"quantity": "1",
"unit-price": "49.50",
"total": "49.50"
}
],
"total": "69.00"
}
Response by API
{
"applied_discounts": [
{
"id": 3,
"name": "Tools Discount",
"description": "Seems like you really like Tools, here's one for free!"
}
],
"discounted_items": [
{
"product-id": "A101",
"quantity": "2",
"unit-price": "9.75",
"total": "19.50",
"discounted_price": 15.6
}
],
"discounted_price": 65.1,
"original_price": "69.00"
}
Now when I try to make unit test, this is what I came up with:
public function testToolsDiscount()
{
$this->json('POST', '/discount',
[
'customer-id' => '3',
'items' => [
[
'product-id' => 'A101',
'quantity' => '2',
'unit-price' => '9.75',
'total' => '19.50'
],
[
'product-id' => 'A102',
'quantity' => '1',
'unit-price' => '49.50',
'total' => '49.50'
]
],
'total' => '69.00'
])
->seeJson(
[
'applied_discounts' => [
[
'id' => 3,
]
],
]);
}
However when I run it, this is the error I get
DiscountTest::testToolsDiscount Invalid JSON was returned from the
route. Perhaps an exception was thrown?
What am I doing wrong?
Make sure your route matches the specified '/discount' with any prefix it may have.
Define the proper route,
I recommend using action() Helper function to add url, the main benefits of this function is when you change some text or prefix in route,
Let say you change from /discount to /discounts in these case you don't need to change the route everywhere.
action('ControllerName#actionName');
It's possible your post-body needs to be an actual JSON string, rather than an associative array. It's also possible that the json() method requires a fully-qualified URL instead of a relative path. If either is the case, this solution may not actually expose the problem, you'll just have to try them and see. Otherwise, try this, it should at least offer some clues as to what's going wrong. Add the following to your unit-test class and dd() the results.
/**
* #param string $uri
* #param string $method
* #param array $body
* #param array $headers
* #param array $files
* #param array $cookies
* #return array
*/
public function callRoute(
$uri,
$method = 'GET',
array $body = [],
array $headers = [],
array $files = [],
array $cookies = []
) {
foreach ($cookies as $name => $cookie) {
$this->app->resolving(\App\Http\Middleware\EncryptCookies::class, function (\App\Http\Middleware\EncryptCookies $cookie) use ($name) {
$cookie->disableFor($name);
});
}
$uri = trim($uri, '/');
$uriParts = parse_url($uri);
//This value may be based on the APP_URL value in your .env, I'm not really sure.
$root = !array_get($uriParts, 'host') ? trim(app(\Illuminate\Http\Request::class)->root(), '/').'/' : '';
$uri = "$root$uri";
$server = $this->transformHeadersToServerVars($headers);
$response = $this->call($method, $uri, $body, $cookies, $files, $server);
$headers = $response->headers->all();
$code = $response->getStatusCode();
$json = $content = $response->getContent();
$json = json_decode($json, true);
$content = ($json && json_last_error() == JSON_ERROR_NONE) ? $json : $content;
return compact('code', 'headers', 'content');
}
I'd be willing to bet the following will expose an error message and stack trace. You'll likely have to follow it up with some other dd() statements in your target controller, or wherever else your logic lives after that error points you in the right direction:
$body = [
'customer-id' => '3',
'items' => [
[
'product-id' => 'A101',
'quantity' => '2',
'unit-price' => '9.75',
'total' => '19.50'
],
[
'product-id' => 'A102',
'quantity' => '1',
'unit-price' => '49.50',
'total' => '49.50'
]
],
'total' => '69.00'
];
$response = $this->callRoute('POST', '/discount', $body)['content'];
dd($response);
I have a Webhook I am trying to configure. A user fills out a form, and it is connected to a Webhook as well to send the form data to another location. Doesnt seem to be working, when I submit the form, the webhook destination doesn't seem to be processing/sending the data.
Here is the Json Data:
data.json { "Account_Name": [ "Test Name" ], "Email": [ "test#test.com" ], "Phone": [ "5555555555" ], "camp_id": [ "18052" ], "hs_a_t": [ "1360223458579" ], "ip_address": [ "" ], "referrer": [ "" ], "source": [ "3" ], "time_submitted": [ "07:51 AM UTC" ] }
data.xml <?xml version='1.0'?> <form_data> <Account_Name>Test Name</Account_Name> <Phone>5555555555</Phone> <Email>test#test.com</Email> <camp_id>18052</camp_id> <hs_a_t>1360223458579</hs_a_t> <source>3</source> <referrer/> <ip_address></ip_address> <time_submitted>07:51 AM UTC</time_submitted> </form_data>
extra_data.json { "rapleaf": {} }
extra_data.xml <?xml version='1.0'?> <extra_data> <rapleaf/> </extra_data>
page_id a75948fc-70f6-11e2-8dd8-12313e008101
page_name Test
page_url http://unbouncepages.com/test33333
variant a
Here is the php code the webhook points to:
<?php
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
if (get_magic_quotes_gpc()) {
$unescaped_post_data = stripslashes_deep($_POST);
} else {
$unescaped_post_data = $_POST;
}
$form_data = json_decode($unescaped_post_data['data_json']);
/*******************************
PARSE DATA FROM UNBOUNCE
*******************************/
$email_address = $form_data->email[0];
$page_id = $_POST['page_id']; //Unbounce Page ID
$page_url = $_POST['page_url']; //Unbounce Page URL
$variant = $_POST['variant']; //Unbounce Page Variant
function mytheme_post_to_another_script($form)
{
// Rewrite the post variables
$post = array(
'Account_Name' => $_POST['name'], // Change iphorm_X_X to name field unique ID
'Email' => $_POST['email_address'], // Change iphorm_X_X to email field unique ID
'Phone' => $_POST['phone_number'], // Change iphorm_X_X to phone field unique ID
'Website_URL' => $_POST['iphorm_1_4'],
'Camp_ID' => $_POST['Camp_ID'],
'Source' => $_POST['Source'],
'Email_List_ID' => $_POST['Email_List_ID'],
'hs_a_t' => $_POST['hs_a_t']
);
// Create a new cURL resource
$ch = curl_init();
// Set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, 'http://Reports.rankupmedia.com/Client/Sales/Lead/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
// Grab URL and pass it to the browser
curl_exec($ch);
// Close cURL resource, and free up system resources
curl_close($ch);
}
?>