Range query on subfield array with elasticsearch - php

I'm trying to get all the services with a code different than 0, I don't find any way to do it without doing multiple queries.
Here's the data i'm trying to query, thanks in advance for the help
"hits": [
{
"_index": "database_index",
"_type": "system",
"_id": "AV03gG7B3dd3_xKqi09H",
"_score": 1,
"_source": {
"name_id": "BOX",
"room_id": "63190",
"event": "SysMonitor",
"data": {
"ip": "192.168.60.25 \n",
"ns": "192.168.0.1\n",
"uptime": "3:12"
},
"services": {
"apache2": 1,
"gw-flash": 0,
"appmgr": 0,
"watchdog": 2,
"gui": 0,
"usb": 0,
"internet": 0
},

This is a classic fulltext search example, where one could write a very complicated query to cover this or you could optimize this on index time and thus have very cheap queries. If you change your data model to have a field that contains all the services that have a value of 0 or 1, you could easily search for that, i.e.
services_zero: [gwflash, appmgr]
services_one: [ apache2 ]
Suddenly your query can easily search or aggregate against those fields.
Not saying that this will perfectly fit your use-case, but I think it is worth to rethink the data modelling strategy here.

Related

Laravel - Eloquent to Json, and then sortBy on json object not working

I have this json value that I want to be sorty but for some reason it's not working.
[
{
"id": 15028,
"order_id": 342,
"user_id": 3,
"status": "1",
"priority": "1",
"donedate": null,
"user": {
"id": 3,
"name": "Max"
}
},
{
"id": 15030,
"order_id": 341,
"user_id": 4,
"status": "2",
"priority": "1",
"donedate": null,
"user": {
"id": 4,
"name": "Jon"
}
}
]
This jSon structure is the result of Laravel eloquent object conversion using $object->toJson();
Now I keep this output in my Redis cache. What I want is to when the status and or priority of any order gets changed then I want to sort this jSon and store it back in Redis.
$order_list = collect($json_decoded_with_updated_values);
$order_list = $order_list->sortBy('status')->sortBy('priority');
Redis::set(\GuzzleHttp\json_encode($stich_list_in_collection));
Redis::set("orders_list", $orders_list, 302400);
However, I don't get a sort list. What I want to achieve is that, just like I would run two to three orderBy on an eloquent model like orderBy('status')->orderBy('priority')->get() .. I want to run the same two sortings on this json list.
Thanks in advance.
I figured it out. Actually we don't need to have a call-back as suggested by #brokedid. We can do it like following.
$order_list->sortBy('status')->sortBy('priority')->values()->all();
So I was missing the "->values()->all()" part. I hope if any one runs into the same problem in future, they can get a hint from this.
If you want to sort by multiple Fields, then you could try to sort with a callback-method:
$orderedList = $unorderedList->sortBy(function($item) {
return $item->priority.'-'.$item->status;
});
I wonder what's the result when you choose a different sort direction.
$order_list = $order_list->sortByDesc('status');

HERE Api: Using Positioning APIto get Lat and Long

I'm trying to use the Using Positioning API to search for the latitude and longitude of a given point, however I only have MCC, MNC, TimeAdvance, LAC, Cell_ID, and Signal Power. How can I use this data to fetch the location?
I tried to use as below but did not return any data.
{
"gsm": [
{
"mcc": 724,
"mnc": 10,
"lac": 2397,
"cid": 453,
"nmr": [{ "bsic": "0", "bcch": "0" }]
},
{
"mcc": 724,
"mnc": 10,
"lac": 2397,
"cid": 3045,
"nmr": [{ "bsic": "0", "bcch": "0" }]
}
]
}
Im using cURL.
Thanks
This response means that you have sent a valid request for which the API cannot determine a location.
I have tried to find the cell towers in your request using various cell tower databases and I could not find them anywhere. If they do exist they are most likely not in our (or any) database at this point.

How to give empty conditions in controller of cakephp 3.2 during model bind?

I am new to cakephp 3.
Below is my code.
$getFlags = $this->Posts->find('all')->contain(['Users', 'Flags.Users', 'Flags.FlagReasons', 'Flags.Users.Schools']);
output
{
"id": 114,
"title": "",
"allow_comment": 0,
"owner_id": 84,
"created": "2016-04-08T04:41:08+0000",
"status": 1,
"flags": [],
"user": {
"id": 84,
"profile_image": "bc7484cd8caad0de055f8d7ef15551f5.png",
"is_active": 1
}
Here i want to give a condition,when there is an empty flag ,it will not be listed in result.
Only post having flag will come.
Please suggest me.
ANy suggstion will highly appreciate.
There are two ways to get this done:
Use a counter cache and filter by that field (flag_count > 0)
Do a subquery to get the count (inefficient)

advanced search with ElasticSerach

I've create a small application with PHP and I use ES.
My request is good, but I've got the good result.
My request look-like that:
link:9200/index/_search?from=0&size=130&q=try:'yes'
%2Bbrand:'BMW' %2Bmodel:'SERIE 5' %2Bprice:[500 TO 700000]
When I send this query, ES reply me with model 'SERIE 3' and 'SERIE 5', it's great, but when I send this query, I would like to recover only 'BMW' and 'SERIE 5'.
How can I fix this?
First, you should take a look at the documentation to be more familiar with these notions (analyze / difference between query and filters) which are very important for a good use of ElasticSearch. You can find a good getting started documentation here.
Your problem is that your "model" field is a string, which by default is analyzed using the standard analyzer.
It outputs 2 tokens because of the whitespace in the model name as you can see if you use the _analyze endpoint :
GET _analyze?analyzer=standard&text='Serie 5'
{
"tokens": [
{
"token": "serie",
"start_offset": 1,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "5",
"start_offset": 7,
"end_offset": 8,
"type": "<NUM>",
"position": 2
}
]
}
On top of that, you're using a query and though will return all results matching even partially. So, you're certainly having the two cars in your results, but the "SERIE 5" car must be the first (as it matches better) than the car "SERIE 3", which is represented by a higher _score attribute.
You need to use a term filter which will return only the documents containing the term value you provided.
However, as it works on terms, you have to change the mapping of your field to "not_analyzed" like this to keep it as it is :
PUT /test/car/_mapping
{
"properties":{
"model":{
"type": "string",
"index":"not_analyzed"
}
}
}
Finally, the search request will be something like this (with price criteria as range filter and the use of a and filter to combine both) :
GET /test/car/_search
{
"query": {
"filtered": {
"filter": {
"and": {
"filters": [
{
"term": {
"model": "Serie 3"
}
},
{
"range": {
"price": {
"from": 500,
"to": 70000
}
}
}
]
}
}
}
}
}
Your query (url_decoded) looks like
link:9200/index/_search?from=0&size=130&q=try:'yes' +brand:'BMW' +model:'SERIE 5' +price:[500 TO 700000]
I think you are using '+' incorrectely, so that it is doing or operation for your query,
If you want to get with try:yes, brand:BMW and model:SERIE 5 then you have to join these query by AND keyword.
like.
link:9200/index/_search?from=0&size=130&q=try:'yes'
AND brand:'BMW' AND model:'SERIE 5' AND price:[500 TO 700000]
And you should be aware of choosing analyzer (in mapping of fields), so that things are indexed as you want.
It will work, Thanks
Reference

Using AND on same key in mongodb

I have a key in my document whose structure is as follow:
"tag": [
{
"schemeName": "http:\/\/somesite.com\/categoryscheme2",
"name": "Test Tag2",
"value": 1,
"slug": "test_tag2"
},
{
"schemaName": "http:\/\/somesite.com\/categoryscheme3",
"name": "Test Tag3",
"value": 1,
"slug": "test_tag3"
}
]
Now, I get inputs as tag=test_tag2ANDtest_tag3. How can I write a query for this?
I tried to iterate through the loop but I didnt got any results.
Correct me if I am wrong but you don't need an $and or $elemMatch, instead:
$mongodb->collection->find(array('tags.slug'=>array(
'$in' => array('test_tag2','test_tag3'))))
Should work, however, if your English suggests what a second read does, then you can also use $all in place of $in. This will ensure that all root documents must have those slugs in them.
use $elemMatch operator to match elements inside the array.

Categories