I have in my Algolia engine the next "entity"
Professional
objectID: "eyJpZCI6OX0="
...
status: id: 1
And I like to make a search just with the ones that have status = 1.
I've tried this:
$searchResult = $this->get('algolia.indexer')->rawSearch(Professional, $data, [
'hitsPerPage' => 10,
'page' => 1,
'facetFilters' => 'status:1',
]);
Seems that im nos using facetFilters correctly,
any help?
Thanks
From what I can see you have sub-attribute id inside the status attribute. So your record looks something like this:
{
"objectID": "eyJpZCI6OX0=",
...
"status": {
"id": 1
}
}
Correct?
In this case you need to specify the sub-attribute in your facetFilters as well. In your case it would look like this:
$searchResult = $this->get('algolia.indexer')->rawSearch(Professional, $data, [
'hitsPerPage' => 10,
'page' => 1,
'facetFilters' => 'status.id:1',
]);
If you use Algolia PHP API client, the code would look like this:
$client = new \AlgoliaSearch\Client('foo', 'bar');
$index = $client->initIndex('index_name');
$res = $index->search('', ['filters' => 'status.id:1']);
You can also replace facetFilters parameter by filters parameter, which is more powerful and allows you to specify more complex conditions.
Related
I have a collection which contains these values
'sales marketing|telemarketing',
what I'm trying to do is query/filter the items in collection but just based on the individual type so the for example value of 'telemarketing'. I have tried
$results = $data->where('Department', 'contains', $type); and also tried LIKE but because of the format with the pipe it's not picking the type/value.
This might be a dumb question but any ideas would be great!
The where-method also can handle only two Parameters. For example:
$data= collect([
['Department' => 'sales', 'price' => 200],
['Department' => 'marketing', 'price' => 100],
['Department' => 'telemarketing', 'price' => 150],
['Department' => 'marketing', 'price' => 100],
]);
$departmentName = "marketing";
$results = $data->where('Department', $departmentName);
dd($results);
Given your example:
[
"Employee" => "Some Company",
"Name" => "John Something",
"Usages" => "sales marketing|telemarketing",
"StartDate" => "1st Mar 2021",
"EndDate" => ""
]
The main issue is that the "Usage" property is a string containing multiple values, with the pipe character acting as a separator.
One solution to filter by one of those values is by mapping your original collection to transform the string in an array with the explode method and then use the filter method to filter based on the Usages you're interested in.
The resulting code might look like this:
$mappedCollection = $collection->map(function($el) {
$el['Usages'] = explode('|', $el['Usages']); // Transform the string into an array
return $el;
});
$result = $mappedCollection->filter(function($el) {
return in_array('sales marketing',$el['Usages']); // Change 'sales marketing' with the desired Usage
});
I want to display all documents (select *) with sub-documents in PHP.
I know how to query all find() but I have no idea how to do it when I have sub-documents. I don't know if there's something like find() or I need to make loops fo every sub-documents that I'd have.
This would be the code
$mongodatabase->insertOne(
['name' => 'Alex',
'surname' => 'Turner',
'country' => 'England',
'birth' => array(
'day' => 6,
'month' => 'january',
'year' => 1986
),
]);
Something easy, just to learn. When I try a var_dump of day I get Undefined index and NULL.
$client = new MongoDB\client;
$db = $client->database;
$mongodatabase = $db->document;
$document = $mongodatabase->find();
foreach ($document as $doc) {
var_dump($doc->day);
}
However, I'd like to query all.
Use $exists - It helps us in identifying the elements which are not empty
db.collection_name.find({
"birth.day" : {
$exists : true
}
});
If you need to check not null and empty, then we need to use $type together with $exists, $type can be passed with different values and 10 is for null check
db.collection_name.find({
"birth.day" : {
$not : { $type : 10 },
$exists : true
}
});
when u find the exactly data from mongoldb u can use the shelter to limit the field
eg:
db.xxxxx.find(
{'status':'DELIVRD'}
);
i have a document like bellow, now i will to figure out which element in friendsR whose readable & 2 is grater than 0. anyone here can help me? thank you.
[code]
$doc = array('friendsR' => array(
array('friend_id'=>100, 'readable' => 7, 'bridge'=>5),
array('friend_id'=>100, 'readable' => 7, 'bridge'=>6),
array('friend_id'=>100, 'readable' => 7, 'bridge'=>7))
);
datamodel()->insert($doc);
$macher = array('$bit' => array( 'friendsR.$.readable' => array('and'=>2) ));
$cursor = datamodel()->find($macher);
[/code]
The $bit operator is an "update operator", so it is used to change values and not query them.
If you need this sort of query you need a JavaScript evaluation such as $where:
For a document that looks like this in the shell:
{
"friendsR": [
{ 'friend_id': 100, 'readable': 7, 'bridge': 5 },
{ 'friend_id': 100, 'readable': 7, 'bridge': 6 },
{ 'friend_id': 100, 'readable': 7, 'bridge': 7 }
]
}
To just find documents that have a matching element you would do this:
$macher = array(
'$where' => new MongoCode("function(){
return this.friendsR.some(function(x) {
return ( x.readable & 2 ) > 0
})
}")
);
To actually return "which elements" matched you would again have to do something like this with mapReduce. It will "mark" which items in the array met the condition and only return documents where at least one array member that matches.
$map = new MongoCode("function(){
this.friendsR.forEach(function(friend) {
friend.macthed = ( ( friend.readable & 2 ) > 0 );
});
if ( this.friendsR.some(function(x) { return x.matched }) )
emit( this._id, this );
}");
$reduce = new MongoCode("function(){}");
$result = $db->command(array(
"mapreduce" => "collection_name",
"map" => $map,
"reduce" => $reduce,
"out" => array( "inline" => 1 )
));
There are no built in operators for bitwise evaluation so JavaScript is your only option where it is available.
Note that the mapReduce is a command and must be run from a Db object, the result is either returned inline as shown or output to another collection. This does not return a cursor. See the official documentation on mapReduce for more information.
I have MongoDB collection of documents containing several fields. One of the columns/fields should be numeric only, but some of these fields contain non-numerical (corrupt) data as string values. I should find the highest numerical value of this column, excluding the corrupt, non-numerical data. I am aware of the question Getting the highest value of a column in MongoDB, but AFAIK, this extended case was not covered.
The example below depicts the issue. For the highest value, the document with "age": 70 should be returned:
[
{
"id": "aa001",
"age": "90"
},
{
"id": "bb002",
"age": 70
},
{
"id": "cc003",
"age": 20,
}
]
Providing a PHP example for the find() / findOne() query would be of much help. Thanks a lot!
JohnnyHK came up with the perfect solution. Here's the working PHP code:
$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('age' => -1))->limit(1);
You can use the $type operator with $not in your query to exclude docs where age is a string. In the shell your query would look like:
db.test.find({age: {$not: {$type: 2}}}).sort({age: -1}).limit(1)
Or in PHP from Martti:
$cursor = $collection->find(array('age' => array('$not' => array('$type' => 2))), array('age' => 1));
$cursor->sort(array('price' => -1))->limit(1);
with PHP driver (mongodb)
using findOne()
$filter=[];
$options = ['sort' => ['age' => -1]]; // -1 is for DESC
$result = $collection->findOne(filter, $options);
$maxAge = $result['age']
You can use aggregate function to get maximum number from collections like this.
$data=$collection->aggregate(array
( '$group'=>
array('_id'=>'',
'age'=>array('$max'=>'$age'.)
)
)
);
This works for me
$options = ['limit' => 100,'skip' => 0, 'projection' => ['score' => ['$meta' => 'textScore']], 'sort' => ['score' => ['$meta' => 'textScore']]];
I need to make a query like this:
db.subscribers.find({LISTID: 59, {$or: [{LANG: {$in: ['English', 'Spanish']} },
{LANG: {$nin: ['Russian']} }]} });
It's supposed to get all subscribers from listid 59, who know English or Spanish or(and) doesn't know Russian. Instead of language there could be any field that can have multiple values.
It looks like this query works in mongodb console.
In this case one field can be in several conditions.
I there is the same field wouldn't be in several conditions, maybe it could be something like:
$collection->find(array('LISTID' => $listId,
array('$or' = array(LANG => array('$in' => array('English','Spanish')),
/*some other condition united with OR*/
)));
How to make this query in php?
It's supposed to get all subscribers from listid 59, who know English or Spanish and doesn't know Chinese.
If that's the objective of your query (I assume you mean "Russian" instead of "Chinese"), I don't see how your original console query works:
db.subscribers.find({
LISTID: 59,
{ $or: [
{ LANG: { $in: ["English", "Spanish"] } },
{ LANG: { $nin: ["Russian"] } }
] }
});
$or needn't be nested in its own object according to the documentation. Also, if you're looking for documents with a given LISTID that know two languages but not another, $and seems more appropriate:
db.subscribers.find({
LISTID: 59,
$and: [
{ LANG: { $in: ["English", "Spanish"] } },
{ LANG: { $ne: "Russian" } }
]
});
This would translate to PHP as:
$collection->find(array(
'LISTID' => $listId,
'$and' => array(
array('LANG' => array('$in' => array('English', 'Spanish'))),
array('LANG' => array('$ne' => 'Russian')),
),
));
I think the solution is something like this:
$number = $collection->find(array('LISTID' => $listId,
'$or' => array( array('LANG' => array('$in' => array('English', 'Spanish'))),
array('LANG' => array('$nin' => array('Russian'))),
) ))->count();
// Find record according to specific column
$getfollower = $dbnew1->find(array('follower' => $follower),
array('page_name' => 1, 'id'=>1, '_id'=>0));