Dgraph: How do you query for strings that start with a specific sequence of letters? - dgraph

For example, let's say your database contains a bunch of People{ name } objects, and you want to find everyone whose name starts with the letter "H" or "Mi".

You should use Regex https://docs.dgraph.io/query-language/#regular-expressions
But, regex accepts at least 3 characters.
Other way you could do is using "has" function and ordering by the predicate.
https://docs.dgraph.io/query-language/#has
{
me(func: has(name), first: 50, orderasc: name) {
name
}
}
But with 'Has' function you don't have full control. It will follow an alphabetical order.
One way to have this level of control is to create a pseudo-indexing structure. Every time you add a user you relate him to a tree that will play the role of indexing. And through this tree you can count and traverse the edge.
e.g:
Let's assume you know the UID of your tree (or that you use Upser Block).
_:NewUser <name> "Lucas" .
_:NewUser <pred1> "some1" .
_:NewUser <pred2> "some2" .
# Now we gonna relate Lucas to our tree and <0x33f> is the uid for the letter L of "Lucas"
<0x33f> <firstCharacter> _:NewUser . #This is a reverse record (you don't need to use #reverse tho)
The same example using Upsert Block:
upsert {
query {
v as var(func: type(myTree)) #filter(eq(letter, "L"))
}
mutation {
set {
_:NewUser <name> "Lucas" .
_:NewUser <pred1> "some1" .
_:NewUser <pred2> "some2" .
uid(v) <firstCharacter> _:NewUser .
}
}
}
A basic search in the tree would be like:
{
q(func: type(myTree)) #filter(eq(letter, "L")) {
letter
firstCharacter { name pred1 pred2 }
}
}
Or
{
q(func: type(myTree)) #filter(eq(letter, "L")) {
letter
count(firstCharacter)
}
}
Cheers.

Related

Swift + Markdown: plain text is changed after reading and writing to file

I'm using Apples own Markdown framework (https://github.com/apple/swift-markdown) and when I have a markdown file like the following:
## this is my heading 2
- this is some unordered list entry
- and another one
- and still anther one
- and an indented one
When I read and write without any changes:
let data = FileManager.default.contents(atPath: "myfile.md")!
var document = Document(parsing: String(data: data, encoding: .utf8)!)
let url = URL(filePath: "myfile.md")
try document.format(options: .init()).data(using: .utf8)!.write(to: url)
the content changes:
## this is my heading 2
- this is some unordered list entry
- and another one
- and still anther one
- and an indented one
i.e. a newline is printed after the heading and the indention of the unordered list is changed to two spaces instead of 4/tab. Is there a way to prevent/configure this?
No, you cannot configure either of these without creating your own fork of swift-markdown. For the extra newline, take a look at this code:
mutating public func visitUnorderedList(_ unorderedList: UnorderedList) {
if unorderedList.indexInParent > 0 && !(unorderedList.parent?.parent is ListItemContainer) {
ensurePrecedingNewlineCount(atLeast: 2)
}
descendInto(unorderedList)
}
mutating public func visitOrderedList(_ orderedList: OrderedList) {
if orderedList.indexInParent > 0 && !(orderedList.parent?.parent is ListItemContainer) {
ensurePrecedingNewlineCount(atLeast: 2)
}
descendInto(orderedList)
}
Observe the ensurePrecedingNewlineCount(atLeast: 2) call.
For the indentation of lists, take a look at this code from the swift-markdown repository:
} else if element is UnorderedList {
if unorderedListCount > 0 {
prefix += " "
}
unorderedListCount += 1
} else if element is OrderedList {
if orderedListCount > 0 {
prefix += " "
}
orderedListCount += 1
} else if !(element is ListItem),
let parentListItem = element.parent as? ListItem {
/*
Align contents with list item markers.
Example, unordered lists:
- First line
Second line, aligned.
Example, ordered lists:
1. First line
Second line, aligned.
1000. First line
Second line, aligned.
*/
if parentListItem.parent is UnorderedList {
// Unordered list markers are of fixed length.
prefix += " "
} else if let numeralPrefix = numeralPrefix(for: parentListItem) {
prefix += String(repeating: " ", count: numeralPrefix.count)
}
Note the hardcoded spaces to add to the prefix variable when elements are children of lists.
It's worth noting that at least the extra newline is required by the Markdown spec, and some parsers will not properly read the markdown unless there are two newlines between each logical "section" (paragraph, list, block quote, code block, etc.). I'm not sure whether the indentation is required by the spec, but that may also be why the team at Apple made that decision.
Also, one thing that may make this more understandable is that when you parse your markdown document, it represents the document in a tree structure like this:
// Document
// └─ Paragraph
// ├─ Text "This is a markup "
// ├─ Emphasis
// │ └─ Text "document"
// └─ Text "."
and so it has completely forgotten about your formatting. When you then write it back out, it generates Markdown text from this tree. So although you made no changes to the document in your code, it has been parsed and then the Markdown is regenerated, rather than keeping your original document in memory exactly as-is and modifying it on the fly.

In VSCode snippets how do you use transform to lowercase just the first letter of a value?

I've just started getting into vsCode snippets. They seem really handy.
Is there a way to ensure that what a user entered at a tabstop starts with a lowercase value.
Here's my test case/ sandbox :
"junk": {
"prefix": "junk",
"body": [
"original:${1:type some string here then tab}",
"lower:${1/(.*)/${1:/downcase}/}",
"upper:${1/(.*)/${1:/upcase}/}",
"capitalized:${1/(.*)/${1:/capitalize}/}",
"camel:${1/(.*)/${1:/camelcase}/}",
"pascal:${1/(.*)/${1:/pascalcase}/}",
],
"description": "junk"
}
and here's what it produces:
original:SomeValue
lower:somevalue
upper:SOMEVALUE
capitalized:SomeValue
camel:somevalue
pascal:Somevalue
"camel" is pretty close but I want to preserve the capital if the user entered a camelcase value.
I just want the first character lower no matter what.
The answer is:
${1/(.)(.*)/${1:/downcase}$2/}
Just to clarify, if you look at this commit: https://github.com/microsoft/vscode/commit/3d6389bb336b8ca9b12bc1e772f7056d5c03d3ee
function _toCamelCase(value: string): string {
const match = value.match(/[a-z0-9]+/gi);
console.log(match)
if (!match) {
return value;
}
return match.map((word, index) => {
if (index === 0) {
return word.toLowerCase();
} else {
return word.charAt(0).toUpperCase()
+ word.substr(1).toLowerCase();
}
})
.join('');
}
the camelcase transform is intended for input like
some-value
some_value
some.value
I think any non [a-z0-9]/i will work as the separator between words. So your case of SomeValue is not the intended use of camelcase: according to the function above the entire SomeValue is one match (the match is case-insensitve) and then that entire word is lowercased.

How to refine a leaf's range in YANG model?

I have a grouping like -
grouping threshold-value-grouping {
container threshold-value {
description "Threshold value";
leaf upper-limit-val {
description
"Upper limit";
type uint32 {
range "1..60000";
}
}
leaf lower-limit-val {
description
"Lower limit";
type uint32 {
range "1..60000";
}
}
}
}
And i want to reuse this grouping at multiple places.
But when used at different places, the range of the leaves vary.
So i am wondering how can I use the refine statement to achieve?
Or is there any better way to address this issue?
Section 7.13.2 of RFC 7950 explicitly specifies all possible refinements and range is not one of them. Neither is type which can also be seen in the ABNF grammar (section 14):
refine-stmt = refine-keyword sep refine-arg-str optsep
"{" stmtsep
;; these stmts can appear in any order
*if-feature-stmt
*must-stmt
[presence-stmt]
*default-stmt
[config-stmt]
[mandatory-stmt]
[min-elements-stmt]
[max-elements-stmt]
[description-stmt]
[reference-stmt]
"}" stmtsep
But what you can do is to add a must constraint here, something like
uses threshold-value-grouping {
refine threshold-value/upper-limit-val {
must '(. >= 10 and . <= 100)' {
error-message "Here you can only use values between 10 and 100";
}
}
}

Scala: mutable.Map[Any, mutable.Map[Any, IndexedSeq[Any]] issue

I have a tiny problem when trying to put an item in my second mutable map.
My objective: gather some elements located in many different xml files, and organise them in the hierarchy they belong (the files are an unstructured mess, with categories being given in seemingly no logical order).
Those elements are: the level in hierarchy of the category (1 - x, 1 is top level) as iLevel, the category code as catCode, its name, and if need be, the name of its parents (all names located in namesCategories).
val categoryMap = mutable.Map.empty[Int, mutable.Map[String, IndexedSeq[String]]]
...
//Before: search in a first file links to other files
// for each category file found, will treat it and store it for further treatement.
matches.foreach{f =>
....
//Will search for a specific regex, and for each matches store what we are interested in
matchesCat.foreach{t =>
sCat = t.replaceFirst((system_env + """\S{4}"""), "")
//iLevel given by the number of '/' remaining in the string
iLevel = sCat.count(_ == '/')
//reset catCode and namesCategories
catCode = ""
namesCategories.clear()
//Search and extract the datas from sCat using premade regex patterns
sCat match {
case patternCatCode(codeCat) => catCode = s"$codeCat"
}
//remove the category code to prepare to extract names
sCat.replace(patternCatCode.toString(), "")
//extract names
do {
sCat match {
case patternCatNames(name) => namesCategories += s"$name"
}
sCat.replace(patternCatNames.toString(), "")
}while(sCat!="")
// create the level entry if it doesn't exist
if(!(categoryMap.contains(iLevel))) {
categoryMap.put(iLevel, mutable.Map.empty[String, IndexedSeq[String]])
}
//Try to add my cat code and the names, which must be in order for further treatment, to my map
categoryMap(iLevel).put(catCode, namesCategories.clone())
}
}
}
Problem:
Type mismatch, expected: IndexedSeq[String], actual: mutable.Builder[String, IndexedSeq[String]]
As Travis Brown kindly noted, I have an issue with a type mismatch, but I don't know how to fix that and get the general idea working.
I tried to keep the code to only what is relevant here, if more is needed I'll edit again.
Any tips?
Thanks for your help

What are all the Unicode properties a Perl 6 character will match?

The .uniprop returns a single property:
put join ', ', 'A'.uniprop;
I get back one property (the general category):
Lu
Looking around I didn't see a way to get all the other properties (including derived ones such as ID_Start and so on). What am I missing? I know I can go look at the data files, but I'd rather have a single method that returns a list.
I am mostly interested in this because regexes understand properties and match the right properties. I'd like to take any character and show which properties it will match.
"A".uniprop("Alphabetic") will get the Alphabetic property. Are you asking for what other properties are possible?
All these that have a checkmark by them will likely work. This just displays that status of roast testing for it https://github.com/perl6/roast/issues/195
This may more more useful for you, https://github.com/rakudo/rakudo/blob/master/src/core/Cool.pm6#L396-L483
The first hash is just mapping aliases for the property names to the full names. The second hash specifices whether the property is B for boolean, S for a string, I for integer, nv for numeric value, na for Unicode Name and a few other specials.
If I didn't understand you question please let me know and I will revise this answer.
Update: Seems you want to find out all the properties that will match. What you will want to do is iterate all of https://github.com/rakudo/rakudo/blob/master/src/core/Cool.pm6#L396-L483 and looking only at string, integer and boolean properties. Here is the full thing: https://gist.github.com/samcv/ae09060a781bb4c36ae6cac80ea9325f
sub MAIN {
use Test;
my $char = 'a';
my #result = what-matches($char);
for #result {
ok EVAL("'$char' ~~ /$_/"), "$char ~~ /$_/";
}
}
use nqp;
sub what-matches (Str:D $chr) {
my #result;
my %prefs = prefs();
for %prefs.keys -> $key {
given %prefs{$key} {
when 'S' {
my $propval = $chr.uniprop($key);
if $key eq 'Block' {
#result.push: "<:In" ~ $propval.trans(' ' => '') ~ ">";
}
elsif $propval {
#result.push: "<:" ~ $key ~ "<" ~ $chr.uniprop($key) ~ ">>";
}
}
when 'I' {
#result.push: "<:" ~ $key ~ "<" ~ $chr.uniprop($key) ~ ">>";
}
when 'B' {
#result.push: ($chr.uniprop($key) ?? "<:$key>" !! "<:!$key>");
}
}
}
#result;
}
sub prefs {
my %prefs = nqp::hash(
'Other_Grapheme_Extend','B','Titlecase_Mapping','tc','Dash','B',
'Emoji_Modifier_Base','B','Emoji_Modifier','B','Pattern_Syntax','B',
'IDS_Trinary_Operator','B','ID_Continue','B','Diacritic','B','Cased','B',
'Hangul_Syllable_Type','S','Quotation_Mark','B','Radical','B',
'NFD_Quick_Check','S','Joining_Type','S','Case_Folding','S','Script','S',
'Soft_Dotted','B','Changes_When_Casemapped','B','Simple_Case_Folding','S',
'ISO_Comment','S','Lowercase','B','Join_Control','B','Bidi_Class','S',
'Joining_Group','S','Decomposition_Mapping','S','Lowercase_Mapping','lc',
'NFKC_Casefold','S','Simple_Lowercase_Mapping','S',
'Indic_Syllabic_Category','S','Expands_On_NFC','B','Expands_On_NFD','B',
'Uppercase','B','White_Space','B','Sentence_Terminal','B',
'NFKD_Quick_Check','S','Changes_When_Titlecased','B','Math','B',
'Uppercase_Mapping','uc','NFKC_Quick_Check','S','Sentence_Break','S',
'Simple_Titlecase_Mapping','S','Alphabetic','B','Composition_Exclusion','B',
'Noncharacter_Code_Point','B','Other_Alphabetic','B','XID_Continue','B',
'Age','S','Other_ID_Start','B','Unified_Ideograph','B','FC_NFKC_Closure','S',
'Case_Ignorable','B','Hyphen','B','Numeric_Value','nv',
'Changes_When_NFKC_Casefolded','B','Expands_On_NFKD','B',
'Indic_Positional_Category','S','Decomposition_Type','S','Bidi_Mirrored','B',
'Changes_When_Uppercased','B','ID_Start','B','Grapheme_Extend','B',
'XID_Start','B','Expands_On_NFKC','B','Other_Uppercase','B','Other_Math','B',
'Grapheme_Link','B','Bidi_Control','B','Default_Ignorable_Code_Point','B',
'Changes_When_Casefolded','B','Word_Break','S','NFC_Quick_Check','S',
'Other_Default_Ignorable_Code_Point','B','Logical_Order_Exception','B',
'Prepended_Concatenation_Mark','B','Other_Lowercase','B',
'Other_ID_Continue','B','Variation_Selector','B','Extender','B',
'Full_Composition_Exclusion','B','IDS_Binary_Operator','B','Numeric_Type','S',
'kCompatibilityVariant','S','Simple_Uppercase_Mapping','S',
'Terminal_Punctuation','B','Line_Break','S','East_Asian_Width','S',
'ASCII_Hex_Digit','B','Pattern_White_Space','B','Hex_Digit','B',
'Bidi_Paired_Bracket_Type','S','General_Category','S',
'Grapheme_Cluster_Break','S','Grapheme_Base','B','Name','na','Ideographic','B',
'Block','S','Emoji_Presentation','B','Emoji','B','Deprecated','B',
'Changes_When_Lowercased','B','Bidi_Mirroring_Glyph','bmg',
'Canonical_Combining_Class','S',
);
}
OK, so here's another take on answering this question, but the solution is not perfect. Bring the downvotes!
If you join #perl6 channel on freenode, there's a bot called unicodable6 which has functionality that you may find useful. You can ask it to do this (e.g. for character A and π simultaneously):
<AlexDaniel> propdump: Aπ
<unicodable6> AlexDaniel, https://gist.github.com/b48e6062f3b0d5721a5988f067259727
Not only it shows the value of each property, but if you give it more than one character it will also highlight the differences!
Yes, it seems like you're looking for a way to do that within perl 6, and this answer is not it. But in the meantime it's very useful. Internally Unicodable just iterates through this list of properties. So basically this is identical to the other answer in this thread.
I think someone can make a module out of this (hint-hint), and then the answer to your question will be “just use module Unicode::Propdump”.