Subquery with NOT IN with MongoDB - php

I would like to create a query with mongodb which would do this thing:
SELECT * FROM Users WHERE Username NOT IN (SELECT LikeTo FROM Like WHERE Username = "John89").
i did something like this:
[
'$lookup'=> [
'from'=> "like",
'let'=> [ 'username'=> '$username' ],
'as'=> "leaders",
'pipeline'=> [
[
'$match'=> [
'$and'=> [
['$expr'=> [ '$not'=> ['$in'=> ['$likeTo','$$username']]]],
['username'=> "$username" ]
]
]
]
]
]
]
but i got PlanExecutor error during aggregation :: caused by :: $in requires an array as a second argument, found: string.
what did i do wrong? is the query right?
thanks!

I would personally split this into 2 queries, but here is how yo achieve this in a single pipeline, we actually want the lookup to match the "bad" users so we can use it to filter, like so:
db.users.aggregate([
{
"$lookup": {
"from": "likes",
let: {
username: "$username"
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$likeTo",
"$$username"
]
},
{
"$eq": [
"$username",
"John89"
]
}
]
}
}
}
],
"as": "leaders"
}
},
{
$match: {
"leaders.0": {
$exists: false
}
}
},
{
$project: {
leaders: 0
}
}
])
Mongo Playground

Related

Combine OR, AND and IN operators in Elasticsearch query

I am very new to the elasticsearch and I need to prepare the query which combines OR, AND and IN operators.
What I want to achieve is having something like this in SQL:
SELECT * FROM tableWHERE (field_1 = 'foo' AND field_2 IN(1,2,3) ) OR ('field_1 = 'bar' AND field_2 IN(2, 3, 4) );
I am using elastic with PHP and have started with something like this:
'query' => [
'bool' => [
'should' => [
[
'match' => [
'field_1' => 'foo',
],
],
[
'match' => [
'field_1' => 'bar',
],
],
],
],
],
However, I cannot add query parameters to achive my desired result. Can you please help me with that?
You need to combine bool/must/should query clauses. For IN operator you can use terms query in elasticsearch
Try out this below query
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"field_1": "foo"
}
},
{
"terms": {
"field_2": [
1,
2,
3
]
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"field_1": "bar"
}
},
{
"terms": {
"field_2": [
2,
3,
4
]
}
}
]
}
}
]
}
}
}

not able to get array in the correct shape

I am trying to create an elasticsearch query and for that I need to get my array in a particular shape but I am not able to get it.
desired output
"query": {
"bool": {
"must": {
"bool": {
"must": [
"match": {
"active": 1
},
"bool": {
"should": [
{
"match": {
"workspace_type.keyword": "lounge"
}
},
{
"match": {
"workspace_type.keyword": " cafe"
}
}
]
}
]
}
}
}
}
My source code
$query = [
'query' => [
'bool' => [
'must' => [
'bool' => [
'must' => []
]
]
]
]
];
$active_query = [
'match' => [
"active" => 1
]
];
$query['query']['bool']['must']['bool']['must'][] = $active_query;
$workspace_type_query = [
'match' => [
"workspace_type.keyword" => "lounge"
]
];
$workspace_type_object = (object) $workspace_type_query;
$query['query']['bool']['must']['bool']['must']['bool']['should'][] = $workspace_type_object;
only issue with this is I am not able to get must[] (the one above match and active ) and it was either coming as an indexed object like
{
"0": {
"match": {
"active": 1
}
}
}
or just an object like this
{
"match": {
"active": 1
}
}
but both these cases are not acceptable for the elasticsearch query that I am trying to generate .. any assistance would be highly appreciated.
I think the extra index that you create for must is wrong.
When you change it to
$query['query']['bool']['must']['bool']['must'] = $active_query;
it seems to work.
The result is
{
"query": {
"bool": {
"must": {
"bool": {
"must": {
"match": {
"active": 1
}
}
}
}
}
}
}

I wanted to check login users follow the search user or not

i want to check login users, follow the search user or not, if follow, true if not,false show in output i need help php cod
MY CODE IS
$sql="SELECT * FROM `users` where user_id='$userid' AND session_id='$session_id'";
$result=mysqli_query($conn,$sql);
if($result->num_rows>0)
{
//user_array
$user_query="SELECT * FROM users";
$user_query_result=mysqli_query($conn,$user_query);
if($user_query_result->num_rows>0)
{
$user_array=array();
while ($row_users = $user_query_result->fetch_assoc())
{
$user_id=$row_users['user_id'];
$user_name=$row_users['fast_name']." ".$row_users['last_name'];
$user_pic_path=$row_users['user_pic_path'];
$follower=array();
$followers=array();
$followed_query="SELECT * FROM followers where follower_id=".$user_id;
$followed_result=mysqli_query($conn,$followed_query);
while($followed_row=$followed_result->fetch_assoc())
{
$follower=$followed_row['user_id'];
if($follower==$user_id)
{
$followers=TRUE;
}
//array_push($followers,$followed_row['user_id']);
}
$images=array();
$images_query="SELECT * FROM image where user_id=".$user_id;
$image_result=mysqli_query($conn,$images_query);
while($image_row=$image_result->fetch_assoc())
{
$images[]=$image_row['image_path'];
}
$user[] = array(
/*"user_id"=>$user_id,*/
"user_name"=>$user_name,
"user_pic_path"=>$user_pic_path,
"follower"=>$followers,
"images"=>$images
);
//add in user_array
array_push($user_array,$user);
}
$response['session']=TRUE;
$response['status']=TRUE;
$response['msg']="user data find successfully";
$response['user_detail']=$user;
echo json_encode($response);
}
MY OUTPUT IS
// 20180104175035
// http://localhost/1111.php?userid=2&session_id=953455543
{
"session": true,
"status": true,
"msg": "user data find successfully",
"user_detail": [
{
"user_name": "asad ali",
"user_pic_path": "localhost/uploads/image/9152108abc",
"follower": [
],
"images": [
"localhost/uploads/image/7947861Discover All In One.png"
]
},
{
"user_name": "asim kabeer",
"user_pic_path": "localhost/uploads/image/1952108xyz",
"follower": [
],
"images": [
"localhost/uploads/image/1787860Discover All In One.png",
"localhost/uploads/image/2152108Mart Zone - All in one.png"
]
},
{
"user_name": "saad hussain",
"user_pic_path": "localhost/uploads/image/5152108ytp",
"follower": [
],
"images": [
"localhost/uploads/image/1474008Mart Zone - All in one.png",
"localhost/uploads/image/6547860Discover All In One.png"
]
},
{
"user_name": "nazeer hussain",
"user_pic_path": "localhost/uploads/image/7352108trp",
"follower": [
],
"images": [
"localhost/uploads/image/1547860Discover All In One.png"
]
},
{
"user_name": "asad zahoor",
"user_pic_path": "localhost/images/ftftft",
"follower": [
],
"images": [
"localhost/uploads/image/1081552Mart Zone - All in one.png"
]
},
{
"user_name": "ali hussain",
"user_pic_path": "localhost/images/sduhsud.png",
"follower": [
],
"images": [
"localhost/uploads/image/5547860Discover All In One.png"
]
}
]
why follower does not show the value i want true or false if follow then show true my follower table schema are following
user_id=>1,2,3,4,5,6
follower_user_id=>2,3,5,3,4,1
I'm almost sure, that below condition is failing
if($follower==$user_id)
{
I'm not sure about the data, so I can't comment much. But, I would suggest to debug your SQL one more time and check, if you are getting expected output from SQL
$followed_query="SELECT * FROM followers where follower_id=".$user_id;
$followed_result=mysqli_query($conn,$followed_query);
while($followed_row=$followed_result->fetch_assoc())
{
$follower=$followed_row['user_id'];
if($follower==$user_id)
Side note : - why can't you simply use follower_id=user_id in SQL ?
$followers=array();
if(1==1)
{
$followers=TRUE;
}
$user[] = array("follower"=>$followers,);
print_r ($user);
Output :
[0] => Array
(
[follower] => 1
)
Whereas, below case return empty array, which is actually your case
if(1==2)
{
$followers=TRUE;
}
$user[] = array("follower"=>$followers,);
print_r ($user);
Output :
[0] => Array
(
)
while ($row_followed = $result_followed->fetch_assoc())
{
//array_push($followers,$row_followed['user_id']);
$age=array($userid=>$row_followed['follower_id']);
foreach($age as $x => $value)
{
if($x==$value)
{
$followers=TRUE;
}
elseif($x!==$value)
{
$followers=FALSE;
}
}
}

Check if a json array value exits on php or not

Hi everyone
I´m making a project where i need to check if a 'x' value, which is being defined on a PHP variable, is founded or not inside the JSON steamid array...
Here is a example of how JSON structure looks like:
{
"users": [
{
"steamid": "[X:X:XXXXXXXXX]",
"teamspeakid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"nicknames": [
"XXXXXXXXX"
],
"addresses": [
"XX.XX.XXX.XX"
]
},
{
"steamid": "[Y:Y:YYYYYYYYY]",
"teamspeakid": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
"nicknames": [
"YYYYYYYYY"
],
"addresses": [
"YY.YY.YYY.YY"
]
},
{
"steamid": "[Z:Z:ZZZZZZZZZ]",
"teamspeakid": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
"nicknames": [
"ZZZZZZZZZ"
],
"addresses": [
"ZZ.ZZ.ZZZ.ZZ"
]
}
]}
The PHP function structure that I have on my mind is similar to this:
if (x value is founded on json->users steamid array) {
$verified = 1;
$teamspeakid = the founded steamid->teamspeakid;
$nicknames = the founded steamid->nicknames;
$addresses = the founded steamid->addresses;
} elseif (steamid value is not founded on json array) {
$verified = 0;
}
I hope you can help me :-)
You need to decode the json array then use strpos to check the string or character exists or not.Do like below:
$jsonarr='{
"users": [
{
"steamid": "[X:X:XXXXXXXXX]",
"teamspeakid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"nicknames": [
"XXXXXXXXX"
],
"addresses": [
"XX.XX.XXX.XX"
]
},
{
"steamid": "[Y:Y:YYYYYYYYY]",
"teamspeakid": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
"nicknames": [
"YYYYYYYYY"
],
"addresses": [
"YY.YY.YYY.YY"
]
},
{
"steamid": "[Z:Z:ZZZZZZZZZ]",
"teamspeakid": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
"nicknames": [
"ZZZZZZZZZ"
],
"addresses": [
"ZZ.ZZ.ZZZ.ZZ"
]
}
]}';
$arr=json_decode($jsonarr,true);
$searchstring='X';
foreach($arr['users'] as $key=>$value){
if (strpos($value['steamid'], $searchstring) !== false) {
$verified = 1;
}else{
$verified = 0;
}
}
or
if(array_search($searchstring, array_column($arr['users'], 'steamid')!== false) {
$verified = 1;
}else{
$verified = 0;
}

What should be the mongoDb query to find number of occurrences?

Sample records in the collection,
(doc 1)
[{
"_id": ObjectId("567941aaf0058ed6755ab3dc"),
"hash_count": NumberInt(7),
"time": [
NumberInt(1450787170),
NumberInt(1450787292),
NumberInt(1450787307),
NumberInt(1450787333),
NumberInt(1450787615)
],
"word": "batman"
},
(doc 2)
{
"_id": ObjectId("567941aaf0058ed6755ab3dc"),
"hash_count": NumberInt(7),
"time": [
NumberInt(1450787170),
NumberInt(1450787292),
NumberInt(1450787307),
NumberInt(1450787333),
NumberInt(1450787354),
NumberInt(1450787526),
NumberInt(1450787615)
],
"word": "apple"
}]
Have stored using PHP,
I want to find the number of records in between time (1450787307) and (1450787615)
Answer:
apple=5
batman=3
What should be query for it?
I ran this command
{
aggregate : "hashtags",
pipeline:
[
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$unwind:"$time"},
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$group:{"_id":"$word","count":{$sum:1}}}
]
}
which gave this result
Response from server:
{
"result": [
],
"ok": 1
}
Since you are stuck with an older version of mongoDB, you cannot leverage the power of the array aggregation operators introduced in 3.2.
You would have to aggregate as below:
db.collection.aggregate([
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$unwind:"$time"},
{$match:{"time":{$gte:NumberInt(1450787307), $lte:NumberInt(1450787615)}}},
{$group:{"_id":"$word","count":{$sum:1}}}
])
translated to PHP,
$result = $c->aggregate([
[ '$match' => [ 'time' => [ '$gte' => NumberInt(1450787307),
'$lte' => NumberInt(1450787615) ] ] ],
[ '$unwind' => '$time' ],
[ '$match' => [ 'time' => [ '$gte' => NumberInt(1450787307),
'$lte' => NumberInt(1450787615) ] ] ],
[ '$group' => [ '_id' => '$word', 'count' => [ '$sum' => 1 ] ] ]
]);
In version 3.2, you could use the combination of $filter and $size to acheive the same result and with less expensive operations.
db.collection.aggregate([
{$match:{"time":{$gte:NumberInt(1450787307),
$lte:NumberInt(1450787615)}}},
{$project:{"_id":0,"word":1,
"count":{$size:{$filter:
{"input":"$time",
"as":"t",
"cond":{$and:[
{$gte:["$$t",NumberInt(1450787307)]},
{$lte:["$$t",NumberInt(1450787615)]}]}
}
}
}
}}
])
ok , after trying a lot I have come with this answer and is correct
for
1450787615- lower limit
1450855155- upper limit
db.hashtags.aggregate([
{
"$match": {
"time": {
"$gte": 1450787615, "$lte": 1450855155
}
}
},
{ "$unwind": "$time" },
{
"$match": {
"time": {
"$gte": 1450787615, "$lte": 1450855155
}
}
},
{
"$group": {
"_id": "$word",
"count": {
"$sum": 1
}
}
}
])
answer is like
{
"result" : [
{
"_id" : "batman",
"count" : 3
},
{
"_id" : "dear",
"count" : 1
},
{
"_id" : "ghost",
"count" : 1
}
],
"ok" : 1
}
db.collection.find({time:{$gt: 1450787307, $lt: 1450787615}});
This will first give you a cursor of all docs that fit within your given time range. Once you have that you can iterate through the cursor and print out the name as well as some loop logic to find the number of occurences for each one. I've only lightly worked with mongodb so there may be a more efficient way to do this.
reference:
https://docs.mongodb.org/v3.0/reference/method/db.collection.find/

Categories