Need a MongoDB query explanation - regex

this is my first question on stackoverflow so be tolerant with a french rookie ;)
I have to simplify a MongoDB query and I've discovered this tool this morning on docs.mongodb.org and I really need to understand the methodology to continue to learn by myself.
Here is the query :
{$and: [{x: 2}, {y: 3}, {$and: [{z: 4}]}, {$or: [{name:{$regex: "toto."}}, {name:{$regex: "toto."}}]}]}
Thanks

Basically in SQL it is:
x = 3 AND y = 3 AND z = 4 AND (name LIKE 'toto%' OR name LIKE 'toto%')
This query can be massively simplified and I am not sure what tool you used to get this query, however, it can be brought down to:
{x: 2, y: 3, z: 4, name: {$in: [/^toto.*/, /^toto.*/]}}
This is since the default operator between query parts is actually $and so you only need $and in very specific cases, i.e. when you need to separately $and two clauses in a field or need to $and two separate $ors that, logically cannot be put together (for some reason).
I should note that in some drivers you need to replace the $in with an $or it depends on the constructs within the driver however, BSON regex objects (not the $regex operator) should be able to function within $in clauses etc.

Related

Get Taxonomy Term ID by Node in Drupal 8

I'm trying to get Taxonomy data by particular node.
How can I get Taxonomy Term Id by using Node object ?
Drupal ver. 8.3.6
You could do something like that:
$termId = $node->get('field_yourfield')->target_id;
Then you can load the term with
Term::load($termId);
Hope this helps.
If you want to get Taxonomy Term data you can use this code:
$node->get('field_yourfield')->referencedEntities();
Hope it will be useful for you.
PS: If you need just Term's id you can use this:
$node->get('field_yourfield')->getValue();
You will get something like this:
[0 => ['target_id' => 23], 1 => ['target_id'] => 25]
In example my field has 2 referenced taxonomy terms.
Thanks!
#Kevin Wenger's comment helped me. I'm totally basing this answer on his comment.
In your code, when you have access to a fully loaded \Drupal\node\Entity\Node you can access all the (deeply) nested properties.
In this example, I've got a node which has a taxonomy term field "field_site". The "field_site" term itself has a plain text field "field_site_url_base". In order to get the value of the "field_site_url_base", I can use the following:
$site_base_url = $node->get('field_site')->entity->field_site_url_base->value;
How to extract multiple term IDs easily if you know a little Laravel (specifically Collections):
Setup: composer require tightenco/collect to make Collections available in Drupal.
// see #Wau's answer for this first bit...
// remember: if you want the whole Term object, use ->referencedEntities()
$field_value = $node->get('field_yourfield')->getValue();
// then use collections to avoid loops etc.
$targets = collect($field_value)->pluck('target_id')->toArray();
// $targets = [1,2,3...]
or maybe you'd like the term IDs comma-separated? (I used this for programmatically passing contextual filter arguments to a view, which requires , (OR) or + (AND) to specify multiple values.)
$targets = collect($field_value)->implode('target_id', ',');
// $targets = "1,2,3"

DynamoDB: Is it possible to get the last element in the list datatype?

I have document that looks like as follows:
{'id': 123,
'favorites': [5, 3, 7, 8, 1, 9, 2]}
In this document, favorite is of list type. I want to query the latest favorite or first/last 5 favorites. I'm not sure how can I achieve that in DynamoDB. Please help.
After hunting for this question for a while, unfortunately it's not supported by the DynamoDB. May be, it'll be supported in the future.
In current(22 Jun 2021) example of documentation, they used size(info.actors) to get the size.
You can do this:
ConditionExpression='#list[0] = :num',
ConditionExpression='size(#list) = :num',
However, you CANNOT do this:
ConditionExpression='#list[ size(#list)-1 ] = :num',
According to
boto3 documentation, it looks like it's impossible to get the last element.
The best work-around I've found so far is:
reverse all lists, then use #list[0]
use contains(#list, :elem)

np.delete and np.s_. What's so special about np_s?

I don't really understand why regular indexing can't be used for np.delete. What makes np.s_ so special?
For example with this code, used to delete the some of the rows of this array..
inlet_names = np.delete(inlet_names, np.s_[1:9], axis = 0)
Why can't I simply use regular indexing and do..
inlet_names = np.delete(inlet_names, [1:9], axis = 0)
or
inlet_names = np.delete(inlet_names, inlet_names[1:9], axis = 0)
From what I can gather, np.s_ is the same as np.index_exp except it doesn't return a tuple, but both can be used anywhere in Python code.
Then when I look into the np.delete function, it indicates that you can use something like [1,2,3] to delete those specific indexes along the entire array. So whats preventing me from using something similar to delete certain rows or columns from the array?
I'm simply assuming that this type of indexing is read as something else in np.delete so you need to use np.s_ in order to specify, but I can't get to the bottom of what exactly it would be reading it as because when I try the second piece of code it simply returns "invalid syntax". Which is weird because this code works...
inlet_names = np.delete(inlet_names, [1,2,3,4,5,6,7,8,9], axis = 0)
So I guess the answer could possibly be that np.delete only accepts a list of the indexes that you would like to delete. And that np._s returns a list of the indexes that you specify for the slice.
Just could use some clarification and some corrections on anything I just said about the functions that may be wrong, because a lot of this is just my take, the documents don't exactly explain everything that I was trying to understand. I think I'm just overthinking this, but I would like to actually understand it, if someone could explain it.
np.delete is not doing anything unique or special. It just returns a copy of the original array with some items missing. Most of the code just interprets the inputs in preparation to make this copy.
What you are asking about is the obj parameter
obj : slice, int or array of ints
In simple terms, np.s_ lets you supply a slice using the familiar : syntax. The x:y notation cannot be used as a function parameter.
Let's try your alternatives (you allude to these in results and errors, but they are buried in the text):
In [213]: x=np.arange(10)*2 # some distinctive values
In [214]: np.delete(x, np.s_[3:6])
Out[214]: array([ 0, 2, 4, 12, 14, 16, 18])
So delete with s_ removes a range of values, namely 6 8 10, the 3rd through 5th ones.
In [215]: np.delete(x, [3:6])
File "<ipython-input-215-0a5bf5cc05ba>", line 1
np.delete(x, [3:6])
^
SyntaxError: invalid syntax
Why the error? Because [3:4] is an indexing expression. np.delete is a function. Even s_[[3:4]] has problems. np.delete(x, 3:6) is also bad, because Python only accepts the : syntax in an indexing context, where it automatically translates it into a slice object. Note that is is a syntax error, something that the interpreter catches before doing any calculations or function calls.
In [216]: np.delete(x, slice(3,6))
Out[216]: array([ 0, 2, 4, 12, 14, 16, 18])
A slice works instead of s_; in fact that is what s_ produces
In [233]: np.delete(x, [3,4,5])
Out[233]: array([ 0, 2, 4, 12, 14, 16, 18])
A list also works, though it works in different way (see below).
In [217]: np.delete(x, x[3:6])
Out[217]: array([ 0, 2, 4, 6, 8, 10, 14, 18])
This works, but produces are different result, because x[3:6] is not the same as range(3,6). Also the np.delete does not work like the list delete. It deletes by index, not by matching value.
np.index_exp fails for the same reason that np.delete(x, (slice(3,6),)) does. 1, [1], (1,) are all valid and remove one item. Even '1', the string, works. delete parses this argument, and at this level, expects something that can be turned into an integer. obj.astype(intp). (slice(None),) is not a slice, it is a 1 item tuple. So it's handled in a different spot in the delete code. This is TypeError produced by something that delete calls, very different from the SyntaxError. In theory delete could extract the slice from the tuple and proceed as in the s_ case, but the developers did not choose to consider this variation.
A quick study of the code shows that np.delete uses 2 distinct copying methods - by slice and by boolean mask. If the obj is a slice, as in our example, it does (for 1d array):
out = np.empty(7)
out[0:3] = x[0:3]
out[3:7] = x[6:10]
But with [3,4,5] (instead of the slice) it does:
keep = np.ones((10,), dtype=bool)
keep[[3,4,5]] = False
return x[keep]
Same result, but with a different construction method. x[np.array([1,1,1,0,0,0,1,1,1,1],bool)] does the same thing.
In fact boolean indexing or masking like this is more common than np.delete, and generally just as powerful.
From the lib/index_tricks.py source file:
index_exp = IndexExpression(maketuple=True)
s_ = IndexExpression(maketuple=False)
They are slighly different versions of the same thing. And both are just convenience functions.
In [196]: np.s_[1:4]
Out[196]: slice(1, 4, None)
In [197]: np.index_exp[1:4]
Out[197]: (slice(1, 4, None),)
In [198]: np.s_[1:4, 5:10]
Out[198]: (slice(1, 4, None), slice(5, 10, None))
In [199]: np.index_exp[1:4, 5:10]
Out[199]: (slice(1, 4, None), slice(5, 10, None))
The maketuple business applies only when there is a single item, a slice or index.

Need Regular expression

I have tried a lot to write a regular expression for below line but could not get the success, so requesting some body to help me out in this.
Exp: "APStress_May-15---11.20.3_UIlog".
In the above example APStress and UIlog will be fix rest of the things will get change. i.e
Month ->May,
date -> 15,
Hour -> 11,
Minute ->20,
Seconds ->3
I am writing a script for analysis the logs for that i have to choose this particular file among others .
APStress.*UIlog. Here .* denotes any characters any number of times. Here is an useful link for your future reference. http://www.regex101.com/
Something like:
APStress_(.*?)-(\d{1,2})---(\d{1,2}).(\d{1,2}).(\d{1,2})_UIlog
(not necessarily the best way of doing it)
Try this:
APStress_([\w]+)-([\d]+)(-){3}([\d]{1,2}).([\d]{1,2}).([\d]{1})_UIlog
You could use named capture groups:
/^APStress_(?<Month>\w+)-(?<Date>\d{1,2})---(?<Hour>\d{1,2}).(?<Minute>\d{1,2}).(?<Seconds>\d{1,2})_UIlog$/
dump%+
outout:
("Hour", 11, "Month", "May", "Date", 15, "Seconds", 3, "Minute", 20)

Regex to calculate straight poker hand?

Is there a regex to calculate straight poker hand?
I'm using strings to represent the sorted cards, like:
AAAAK#sssss = 4 aces and a king, all of spades.
A2345#ddddd = straight flush, all of diamonds.
In Java, I'm using these regexes:
regexPair = Pattern.compile(".*(\\w)\\1.*#.*");
regexTwoPair = Pattern.compile(".*(\\w)\\1.*(\\w)\\2.*#.*");
regexThree = Pattern.compile(".*(\\w)\\1\\1.*#.*");
regexFour = Pattern.compile(".*(\\w)\\1{3}.*#.*");
regexFullHouse = Pattern.compile("((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*");
regexFlush = Pattern.compile(".*#(\\w)\\1{4}");
How to calculate straight (sequences) values with regex?
EDIT
I open another question to solve the same problem, but using ascii value of char,
to regex be short. Details here.
Thanks!
I have to admit that regular expressions are not the first tool I would have thought of for doing this. I can pretty much guarantee that any RE capable of doing that to an unsorted hand is going to be far more hideous and far less readable than the equivalent procedural code.
Assuming the cards are sorted by face value (and they seem to be otherwise your listed regexes wouldn't work either), and you must use a regex, you could use a construct like
2345A|23456|34567|...|9TJQK|TJQKA
to detect the face value part of the hand.
In fact, from what I gather here of the "standard" hands, the following should be checked in order of decreasing priority:
Royal/straight flush: "(2345A|23456|34567|...|9TJQK|TJQKA)#(\\w)\\1{4}"
Four of a kind: ".*(\\w)\\1{3}.*#.*"
Full house: "((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*"
Flush: ".*#(\\w)\\1{4}"
Straight: "(2345A|23456|34567|...|9TJQK|TJQKA)#.*"
Three of a kind: ".*(\\w)\\1\\1.*#.*"
Two pair: ".*(\\w)\\1.*(\\w)\\2.*#.*"
One pair: ".*(\\w)\\1.*#.*"
High card: (none)
Basically, those are the same as yours except I've added the royal/straight flush and the straight. Provided you check them in order, you should get the best score from the hand. There's no regex for the high card since, at that point, it's the only score you can have.
I also changed the steel wheel (wrap-around) straights from A2345 to 2345A since they'll be sorted that way.
I rewrote the regex for this because I found it frustrating and confusing. Groupings make much more sense for this type of logic. The sorting is being done using a standard array sort method in javascript hence the strange order of the cards, they are in alphabetic order. I did mine in javascript but the regex could be applied to java.
hands = [
{ regex: /(2345A|23456|34567|45678|56789|6789T|789JT|89JQT|9JKQT|AJKQT)#(.)\2{4}.*/g , name: 'Straight flush' },
{ regex: /(.)\1{3}.*#.*/g , name: 'Four of a kind' },
{ regex: /((.)\2{2}(.)\3{1}#.*|(.)\4{1}(.)\5{2}#.*)/g , name: 'Full house' },
{ regex: /.*#(.)\1{4}.*/g , name: 'Flush' },
{ regex: /(2345A|23456|34567|45678|56789|6789T|789JT|89JQT|9JKQT|AJKQT)#.*/g , name: 'Straight' },
{ regex: /(.)\1{2}.*#.*/g , name: 'Three of a kind' },
{ regex: /(.)\1{1}.*(.)\2{1}.*#.*/g , name: 'Two pair' },
{ regex: /(.)\1{1}.*#.*/g , name: 'One pair' },
];