how to convert mongo db query in php - php

We have created MongoDB query but it's not converted into PHP
MongoDB query
db.crawled_jobs.aggregate(
[
{
$geoNear: {
near: {
type: "Point",
coordinates: [-73.86, 41.07 ]
},
distanceField:"dist.calculated",
maxDistance: 100000,
includeLocs: "dist.location",
num: 1225,
spherical: true,
"query": { "title": /sales/ }
}
}
])
Mongodb query working fine and we get results
In php \MongoDB\Driver\Command
Create an array in PHP and use for MongoDB query
$queryString = [['$geoNear'=> ['near'=> [ 'type'=> "Point",'coordinates'=> [$lon,$lat] ], 'distanceField'=> "dist.calculated",'maxDistance'=> $maxDistance, 'includeLocs'=> "dist.location", 'num'=> 10000, 'spherical'=> true, 'query' => ['title' => '/sales/'] ] ] ];
after this query, MongoDB query look like this
db.crawled_jobs.aggregate([{"$geoNear":"near":"type":"Point","coordinates":[-73.86,41.07]},"distanceField":"dist.calculated","maxDistance":100000,"includeLocs":"dist.location","num":1225,"spherical":true,"query":{"title":"\/sales\/"}}}])
We didn't get result because it add backslash in query
"query":{"title":"\/sales\/"}
But we need like this "query": { "title": /sales/ }
Can anyone help us
\MongoDB\Driver\Command does not accept string :( it require the only array not string)

Fix it with this
'query' => ['title'=> array('$regex' => 'NYC')]

You need to use MongoDB\BSON\Regex class to generate regex as following:
'query' => ['title' => new MongoDB\BSON\Regex('sales')]

Related

How to ignore query constraints when the parameter is empty or null in elastic search

Elastic Noob here, I have the following query for the elastic search index. in which I try to filter the records based on the title of the product record.
"query" => [
"bool" => [
"should" => [
[
"nested" => [
"path" => "name",
"query" => [
"multi_match" => [
"query" => (string) $query, // here the $query can be empty string
"fields" => ['name.en', 'name.ar'],
],
],
],
],
],
],
];
Now the parameter $query (please see the commented section in the sample code) can be an empty string. In that case, now I am getting zero results, Obviously because I don't have any records with an empty title.
What I would like to get
is to essentially ignore the query since the parameter is empty and to get a default result set back.
I have more queries like category, tags, reviews etc... so even when the name/title query is empty, I should be able to filter based on the other queries. But now if the name part is empty I am getting an empty result set.
Please post a comment if more info is needed
Elasticsearch 7
In a match or multi_match query an empty string will be ingored if one uses zero_terms_query option, like this:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "",
"zero_terms_query": "all",
"fields": ["name.en", "name.ar"]
}
}
]
}
}
}
or match version:
{
"query": {
"bool": {
"must": [
{
"match": {
"name": {
"query": "",
"zero_terms_query": "all"
}
}
}
]
}
}
}
See zero terms query

Doctrine ODM query builder return different results than raw query

I try to get some results filtered with a condition if data does not exist or if exists and is older than...
I have query build with PHP query builder
->addOr(
['interactions.lastDisplays' => ['$elemMatch' => [
'user' => new \MongoId($id),
'date' => ['$lte' => $date]
]]],
['interactions.lastDisplays.user' => ['$ne' => new \MongoId($id)]]
)
And it logs to:
db.Post.find({
"$or": [
{ "interactions.lastDisplays": {
"$elemMatch": { "user": ObjectId("5a61bb816e0bb1542a0bc574"),
"date": { "$lte": new ISODate("2019-06-14T13:22:01+00:00") } } } },
{ "interactions.lastDisplays.user": {
"$ne": ObjectId("5a61bb816e0bb1542a0bc574") }
}]
}).limit(25).skip(0);
For some reason, it does not return any results in PHP. When I copy it and run directly on a database it works fine, and all 25 results are returned.
The solution was as simple as changing $lte to MongoDate.
->addOr(
['interactions.lastDisplays' => ['$elemMatch' => [
'user' => new \MongoId($id),
'date' => ['$lte' => $new \MongoDate($date->getTimestamp())]
]]],
['interactions.lastDisplays.user' => ['$ne' => new \MongoId($id)]]
)
The strange thing that I don't understand yet is that it used to work with DateTime in other queries (but they don't have nested array conditions, so maybe it's the issue). And also that query log is pretty the same.

How to write MongoDB query in core PHP?

I have created query in mongoDB. In MongoChef this query produces more than 10 thousand records in less than 2 seconds. Now I want to execute this query in PHP.
So i don't know how to write query in php as I read various documents on internet but confused how to implement it.
db.PMS.aggregate(
[
{$project:
{EventTS:1,MainsPower:1,PanelID:1}
},
{$unwind:
{path:"$MainsPower",includeArrayIndex:"arrayIndex",preserveNullAndEmptyArrays:true}
},
{ $match: { "MainsPower":{$ne:null}}},
{ $match: { "EventTS":{$gt:new Date("2016-01-01")}}},
{$project:
{MainsPower:1,
PanelID:1,
timestamp:{"$add":
[{'$subtract' : ["$EventTS",new Date("1970-01-01")]},
{"$multiply":[60000,"$arrayIndex"]}
]}
}
}
]
);
You can use some resources available on the php official documentation. A mapping of sql queries in php to mongoDB queries in php can be found here.
Also I have a demo login and registration script at my github. You can view those in this repo.
If you use MongoDB PHP Library you should be able to do something similar to this:
$mongo = new MongoClient();
$database = $mongo->examples;
$collection = $database->PMS;
$pipeline = [
[
'$project' => [
'EventTS' => 1,
'MainsPower' => 1,
'PanelID' => 1,
]
],
[
'$unwind' => [
'path' => '$MainsPower',
'includeArrayIndex' => 'arrayIndex',
'preserveNullAndEmptyArrays' => true
]
],
...
];
$cursor = $collection->aggregate($pipeline);

Correct params for ElasticSearch with PHP

I am attempting to make a Google like search using ElasticSearch and PHP. I have been reading a ElasticSearch book and I think I was to use simple_query_string query type that can take the keywords (or phrase) from a search box and try to find some of all of the terms entered.
I am using the PHP ElasticSearch library in my project and after connecting to my server I am trying to pass a $client->search($params) to my search to return a result.
I have this as my params array
$params =
[
'index' => 'letsmeetup',
'type' => 'person',
'body' =>
[
'query' =>
[
'simple_query_string' =>
[
'query' => $keywords,
'fields' => [
"first_name","last_name","bio","username","email_address","interests","skills"
]
]
]
]
];
I used a phrase like 'People who love php' and I get results. I tried 'real time web' (which is in my bio) as I get the correct result.
Problem is when I try 'Er', knowing there is a first_name of "Erin", or 'Neo', which I have "neo4j" in my bio, it's returning no results. Do I have the params array correct?
You need to use wildcards for these kind of queries
{
"query": {
"query_string": {
"fields": [ "first_name","last_name","bio","username","email_address","interests","skills"],
"query": "Er*"
}
}
}
This will match "Erin", "Eric", "Error" and so on.
You can find more information about Query String Syntax and wildcards here. https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax
I hope this helps!

Is it possible to only use filters without text search in elasticsearch

I am using ES for my Laravel app, and I need to do a search query that only contains filters and no "text search" but I am not sure on how to write it.
Must I use match_all eg:
$query = [
'filtered' => [
'query' => [
'match_all' => []
],
'filter'=> [
'bool' => [
'must' => [
[ 'range' => [
'price' => [
'lte' => 9000
]
]
],
],
]
],
],
];
Or like this:
$query = [
'filtered' => [
'filter'=> [
'bool' => [
'must' => [
[ 'range' => [
'price' => [
'lte' => 9000
]
]
],
],
]
],
],
];
What I want is to only use a filtered bool query without text search.
In fact, if you don't specify the query part in your filtered query, a match_all query is used by default. Quoting the doc :
If a query is not specified, it defaults to the match_all query. This
means that the filtered query can be used to wrap just a filter, so
that it can be used wherever a query is expected.
Your second query should do the job : filters must be wrapped either in filtered (doc) or constant_score (doc) queries to be used.
If the scoring part isn't useful for you, you can stick to the filtered query.
Last thing : you don't have to nest your filter in a bool filter, unless you want to combine it with other(s) filter(s). In your demo case, you can write directly :
$query = [
'filtered' => [
'filter'=> [
'range' => [
'price' => [
'lte' => 9000
]
]
]
]
];
Hope this will be helpful :)
It's actually exactly the same thing since if a query is not specified in the clause it defaults to using the match_all query.
While in query context, if you need to use a filter without a query (for instance, to match all emails in the inbox), you can just omit the query:
GET /_search
{
"query": {
"filtered": {
"filter": { "term": { "folder": "inbox" }}
}
}
}
If a query is not specified it defaults to using the match_all query, so the preceding query is equivalent to the following:
GET /_search
{
"query": {
"filtered": {
"query": { "match_all": {}},
"filter": { "term": { "folder": "inbox" }}
}
}
}
Check here the official documentation: http://www.elastic.co/guide/en/elasticsearch/guide/current/_combining_queries_with_filters.html

Categories