i'll be glad to any help)
for example, i have a collection with objects:
{
playerId: '',
name: '',
link: '',
seat: '',
ownNumber: '',
place: '',
gameNumber: '',
}
how can i get the objects with the highest number in {gameNumber: } ?
$natural: is don't work
You need a sort specifier as well as a limit.
return YourCollection.find({},{sort:{gameNumber: -1},limit:5})
This will return a cursor with the 5 highest gameNumbers, in order from largest to smallest.
Just for your own reference, technically gameNumber is a key, not an object. The entire {...} is a single object.
Related
Here's a minimal example:
import weaviate
CLASS = "Superhero"
PROP = "superhero_name"
client = weaviate.Client("http://localhost:8080")
class_obj = {
"class": CLASS,
"properties": [
{
"name": PROP,
"dataType": ["string"],
"moduleConfig": {
"text2vec-transformers": {
"vectorizePropertyName": False,
}
},
}
],
"moduleConfig": {
"text2vec-transformers": {
"vectorizeClassName": False
}
}
}
client.schema.delete_all()
client.schema.create_class(class_obj)
batman_id = client.data_object.create({PROP: "Batman"}, CLASS)
by_text = (
client.query.get(CLASS, [PROP])
.with_additional(["distance", "id"])
.with_near_text({"concepts": ["Batman"]})
.do()
)
print(by_text)
batman_vector = client.data_object.get(
uuid=batman_id, with_vector=True, class_name=CLASS
)["vector"]
by_vector = (
client.query.get(CLASS, [PROP])
.with_additional(["distance", "id"])
.with_near_vector({"vector": batman_vector})
.do()
)
print(by_vector)
Please note that I specified both "vectorizePropertyName": False and "vectorizeClassName": False
The code above returns:
{'data': {'Get': {'Superhero': [{'_additional': {'distance': 0.08034378, 'id': '05fbd0cb-e79c-4ff2-850d-80c861cd1509'}, 'superhero_name': 'Batman'}]}}}
{'data': {'Get': {'Superhero': [{'_additional': {'distance': 1.1920929e-07, 'id': '05fbd0cb-e79c-4ff2-850d-80c861cd1509'}, 'superhero_name': 'Batman'}]}}}
If I look up the exact vector I get 'distance': 1.1920929e-07, which I guess is actually 0 (for some floating point evil magic), as expected.
But if I use near_text to search for the exact property, I get a distance > 0.
This is leading me to believe that, when using near_text, the embedding is somehow different.
My question is:
Why does this happen?
With two corollaries:
Is 1.1920929e-07 actually 0 or do I need to read something deeper into that?
Is there a way to check the embedding created during the near_text search?
here is some information that may help:
Is 1.1920929e-07 actually 0 or do I need to read something deeper into that?
Yes, this value 1.1920929e-07 should be interpreted as 0. I think there are some unfortunate float32/64 conversions going on that need to be rooted out.
Is there a way to check the embedding created during the near_text search?
The embeddings are either imported or generated during object creation, not at search-time. So performing multiple queries on an unchanged object will utilize the same search vector.
We are looking into both of these issues.
I have read in a lot of sources that I should use the geofield_compute_values() function when trying to programmatically save coordinates in Drupal.
However it does not work for me, that function is undefined in the Drupal 8.5.2 that I am using.
I've installed geofield using composer and I can use it as usual in the admin area and there are no problems with saving there.
Here are some examples I've tried with, the first example gives me undefined function geofield_compute_values() :
$geofield_data = geofield_compute_values([
'lat' => $lat,
'lon' => $lon,
], GEOFIELD_INPUT_LAT_LON);
$cbisProduct->set('field_koordinater', $geofield_data);
I have also tried this out with no successful result and no errors :
$geofield = [
'geom' => "POINT (" . $lon . " " . $lat . ")",
'geo_type' => 'point',
'lat' => $lat,
'lon' => $lon,
'left' => $lon,
'top' => $lat,
'right' => $lon,
'bottom' => $lat,
];
$cbisProduct->set('field_koordinater', $geofield);
Seems like you're trying to use the geofield_compute_values() function which was available in 7.x version, but not in 8.x
You should look into the wkt_generator service. i.e.
<?php $wktGenerator = \Drupal::service('geofield.wkt_generator'); ?>
I haven't tried this, but something like this should work:
<?php
$point = [
'lat' => $request->get('lat'),
'lon' => $request->get('lon'),
];
$value = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($point);
$node->field_koordinater->setValue($value);
Also, WktGeneratorTest.php and GeofieldItemTest.php files could be a good start to see how to use the service in your implementation.
This function is not available in Drupal 8. You have to rely on the basic GeofieldItem class that extends FieldItemBase. Also, as mentioned by oman, you can use WktGenerator to easily build points, polygons, etc.
Here a working example. Let's say your have an entity $cbisProduct with a multivalued geofield field_koordinater, and you want to set the first item with arbitrary lat/lon coordinates :
// Get geofield item
$geofield = $cbisProduct->get('field_koordinater')->get(0);
// Generate a point [lat, lon]
$coord = ['45.909621', '6.127147'];
$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);
// Calling this function will compute values AND assign geodata to the field instance
$geofield->setValue($point);
// You can read the computed geodata from the field
$geodata = $geofield->getValue();
//dpm($geodata);
// Explicitly set field data (needed if $geofield is not a reference)
$cbisProduct->set('field_koordinater', [$geodata]);
// Save entity
$cbisProduct->save();
Under the hood, GeofieldItem::setValue calls another method responsible to directly assign the computed values to the field instance :
# \Drupal\geofield\Plugin\Field\FieldType\GeofieldItem
protected function populateComputedValues() {
/* #var \Geometry $geom */
$geom = \Drupal::service('geofield.geophp')->load($this->value);
if (!empty($geom)) {
/* #var \Point $centroid */
$centroid = $geom->getCentroid();
$bounding = $geom->getBBox();
$this->geo_type = $geom->geometryType();
$this->lon = $centroid->getX();
$this->lat = $centroid->getY();
$this->left = $bounding['minx'];
$this->top = $bounding['maxy'];
$this->right = $bounding['maxx'];
$this->bottom = $bounding['miny'];
$this->geohash = substr($geom->out('geohash'), 0, GEOFIELD_GEOHASH_LENGTH);
$this->latlon = $centroid->getY() . ',' . $centroid->getX();
}
}
Note : You don't necessarily need WktGenerator for building points, as long as you know the geofield type and how geophp should handle it. For example, the following 2 statements are equivalent :
$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);
// is equivalent to
$point = GEOFIELD_TYPE_POINT . '(' . implode(' ', $coord) . ')');
But it is safer to rely on the WktGenerator especially with more complex data types.
I am trying to style just the decimals to look just like this:
Didn't had success, I guess that I need to make my own filter, tried but didn't had success either, I guess it is because I am using it inside a state.
Here the code I am using for the number:
<h2><sup>$</sup>{{salary | number:0}}<sub>.00</sub></h2>
Inside the .app iam using this scope:
$scope.salary = 9000;
Thing is, number can be whatever the user salary is, it get the number from an input, in other places I have more numbers with decimals too.
Possible solutions:
Extract only the decimals from value and print them inside de
tag.
Use a filter to do this?
Use a directive that will split the amount and generate the proper HTML. For example:
app.directive('salary', function(){
return {
restrict: 'E'
, scope: {
salary: '#'
}
, controller: controller
, controllerAs: 'dvm'
, bindToController: true
, template: '<h2><sup>$</sup>{{ dvm.dollar }}<sub>.{{ dvm.cents }}</sub></h2>'
};
function controller(){
var parts = parseFloat(this.salary).toFixed(2).split(/\./);
this.dollar = parts[0];
this.cents = parts[1];
}
});
The easiest solution would be to split out the number into it's decimal portion and the whole number portion:
var number = 90000.99111;
console.log(number % 1);
Use this in your controller, and split your scope variable into an object:
$scope.salary = {
whole: salary,
decimal: salary % 1
}
Protip: Using an object like this is better than using two scope variables for performance
I'm new to rethinkdb and I wanted to filter something like... get all with Kiwi or Strawberry as preferred fruit
{
"id": "65dbaa34-f7d5-4a25-b01f-682032fc6e05" ,
"fruits": {
"favorite": "Mango" ,
"preferred": [
"Kiwi" ,
"Watermelon"
]
}
}
I tried something like this after reading contains doc:
r.db('appname').table('food')
.filter(r.row('fruits').contains(function(doc) {
return doc('preferred').contains('Kiwi');
}))
And I'm getting a e: Cannot convert OBJECT to SEQUENCE in: error.
This is what you're looking for:
r.db('appname').table('food')
.filter((row) => {
r.or( // Returns true if any of the following are true
row('fruits')('preferred').contains('Kiwi'),
row('fruits')('preferred').contains('Strawberry')
)
});
You should know as well, that you can create your own index that calculates this for you, then you'd be able to do a .getAll query using your custom index and return all documents that fit this constraint very quickly.
Lastly, for something that would also work but is probably less efficient on large arrays:
r.db("appname").table('food')
.filter((row) => {
return row('fruits')('preferred').setIntersection(['Kiwi', 'Strawberry']).count().gt(0)
})
I've written a little script that is supposed to create an array that looks something like this:
array(1 => array( 'month' => 'Jan',
'salary' => '01/31/2013',
'bonus' => '02/15/2013'),
2 => array('month' => '',...));
You get the basic idea: the index in the main array are the months (numerically), each holding an array that is to be filled dynamically. The month key depends on the language the user requested, the salary and bonus are assigned the dates when the salary and or bonus was payed. So far no surprizes.
To get the basic structure of that array, I thought this would be the easiest:
$this->months = array_fill_keys(range(1,12), array( 'month' => null,
'salary' => null,
'bonus' => null));
I then fill the array, and things run smoothly all the same, right up until the point where I want to write the data to a file, which I did like so:
private function writeFile()
{
foreach($this->months as $key => $vals)
{
if ($vals['month'] === null)
{//Only filled from date x to date y, some months can be empty
continue;
}
//this seems to raise notices?
if ($vals['salary'] === null)
{
$vals['salary'] = 'Does not apply';
}
fwrite($this->file, implode(',', $vals).PHP_EOL);
}
fclose($this->file);
return $this;
}
The line where I check if the salary is null raises notices: "Warning: Undefined index salary". At the moment I've had to add this to the code:
if (!array_key_exists('salary', $vals) || $vals['salary'] === null)
{
if (!array_key_exists('bonus', $vals) || $vals['bonus'] === null)
{
break;
}
$vals['salary'] = 'Does not apply';
}
To get to the result I need. I have googled this, and stumbled across this bug report, which was last modified 4 years ago (2009-05-08), but the status is still set to "no feedback".
Has anyone else encountered a similar glitch/bug? Or am I missing something here? How can I avoid this issue without the need for all too many if's and function calls without changing my settings (E_STRICT | E_ALL, as it should be).
BTW: I'm running PHP 5.4.7, on Slackware 14. For this little application, I'm using 2 Symfony components (ClassLoader and Console), but since this is part of an object that has nothing to do with Symfony, apart from being loaded through UniversalClassLoader I don't think that's relevant.
Since the bug is said to be PDO related: yes, I am using PDO, but in another class.
I am not sure , but try to use
$this->months = array_fill(1,12, array( 'month' => null,
'salary' => null,
'bonus' => null));
After a couple of var_dumps, I found out what the cause was: The array keys were range(1,12), to determine the which month was I was processing. For that I used a DateTime object in the following fashion:
$date->modify('+ '.$diff.' days');
$key = $date->format('m');
The problem was that the format call returns a string. The goal was to list when the salary and bonus are to be paid. The bonus has to be paid each 15th, or the following Wednesday, if the 15th was a Saturday or Sunday. The salary is to be paid the last day of the month, or the last Friday.
In other words, the bonus pay date is assigned like so:
$key = $date->format('m');
$this->months[$key]['month'] = $date->format('M');
if ($date->format('d') == 15)
{
//find find week-day (15th or following Wednesday)
$this->months[--$key]['bonus'] = $date->format('m/d/Y');
$key++;
//set date to end of month
}
//check week-day, and modify date if required
$this->months[$key]['salary'] = $date->format('m/d/Y');
Because the keys of the $this->months array are numeric, but the format used for $key is a 2-digit string, with leading zeroes, I was having problems.
Each 15th of the month, the $key value is coerced to an integer (decrement/increment operators), but the month is assigned using a string.
The information I provided in my original question was insufficient, sorry for that, but I had just put in an all-nighter. The fix, in the end was pretty easy:
$key = (int) $date->format('m');//cast
I sincerely appreciate all responses, and everyone contributing to the SO community. I would've deleted this question, but if nobody objects, I think I might leave it be as a testimony to my stupidity.