dustjs, duplication check while looping - dust.js

While templating, what is the way to check if an array has same value?
I would like to skip if the array has duplicate value.
[
{name: 1},
{name: 3},
{name: 3},
{name: 4}
]
Sould out 1,3,4 on loop basically. Thanks

In general, Dust follows a philosophy that you should keep logic about your data out of the template. If you need to adjust your data before rendering it, you can write a helper function to pass the data through. Here's an example that uses Lodash's uniqBy to do this.
Context
{
yourArray: [{name: 1}, {name: 3}, {name: 3}, {name: 4}],
unique: function(chunk, context, bodies, {values, by}) {
const uniqueValues = _.uniqBy(values, by);
return chunk.section(uniqueValues, context, bodies);
}
}
Template
{#unique values=yourArray by="name"}
{name}{~n}
{/unique}
In this example, I've defined a context helper unique that accepts two parameters, an array to filter and a key to filter by.
I call _.uniqBy to filter the array, and then use chunk.section to render my block once for each value in uniqueValues.
Then, in the template, I call my context helper {#unique} and pass it the parameters.

Related

Neo4j/Cypher: How to exclude/include nodes with multiple properties?

I have a collection of nodes with multiple properties, for example:
(:Item {id: 1, type: 10})
(:Item {id: 2, type: 10})
(:Item {id: 1, type: 11})
(:Item {id: 1, type: 13})
(:Item {id: 2, type: 11})
In other examples, I can include nodes using a single value, using a query like this (with the IN clause):
MATCH (x:Item)
WHERE x.type IN [10,13]
RETURN x
Im trying to include/exclude nodes with certain properties, something like the next query:
MATCH (x:Item)
WHERE x IN [({id: 1, type: 10}), ({id: 2, type: 11})]
RETURN x
with the above query i don't get an error, but i don't get any results either. Could it be possible so that it includes or excludes certain nodes? In the above example could be more easy do 2-MATCHs for the 2 nodes, but in the real problem i want to include/exclude more than 10 nodes dynamically.
x in your example is much more that just a map with type and id, it is an identifier that represents the complete node.
If you rewrite x as a map of x.id and x.type then you can make that comparison.
MATCH (x:Item)
WHERE {id: x.id, type: x.type} IN [({id: 1, type: 10}), ({id: 2, type: 11})]
RETURN x

Rails query, require all conditions in array

I have two models, both associated with each other through has_many through.
I can query the model and filter based on its associated records:
Car.includes(:equipment).where(equipment: { id: [1, 2, 3] })
The problem is that I want to require all of those records, rather than requiring just one of them.
Is there a way to build a query that requires all of the values in the array (the [1, 2, 3] from the above example).
In other words, I'd like to query for all cars that have all three equipment (ids of 1, 2 and 3).
Assuming you have an id_ary like [1,2,3], how about something like:
id_ary.each_with_object(Car.includes(:equipment)) do |id, scope|
scope.where(equipment: {id: id})
end
Looping like that should and your where conditions, I believe.

neo4j: What is the syntax to set cypher query parameters in the browser interface?

I am trying to run queries from the neo4j browser to reproduce results from my neo4j-javascript-driver client.
What is the syntax for defining query parameters in the neo4j b
I recently attended a neo4j training session in NYC where the trainer (David Fauth) did this, unfortunately, I did not take notes on it, since I figured that I could read-up on this online...but no success.
In neo4j-browser you need type for example:
:params {nodes: [{name: "John", age: 18}, {name: "Phill", age: 23}]}
Then you can use params as usual:
UNWIND {nodes} as node
MERGE (A:User {name: node.name, age: node.age})
RETURN A
For clear params in neo4j-browser type :params {}.
For additional help type :help params.
In Neo4j-3.3.4, the cypher likes this:
:param nodes: [{name: 'John', age: 18}, {name: 'Phill', age: 23}]
Neo4j Browser result:
here
In Neo4j Browser 3.5+ you can use the Cypher Shell parameter syntax, documented here: https://neo4j.com/docs/operations-manual/3.5/tools/cypher-shell/#cypher-shell-parameters
:param name => expression
The expression must be kept on a single line.
The expression could be a scalar or a list:
:param foo => ['a', 'b', 'c']
Maps can't be used directly with this syntax as of Neo4j 4.1. You can wrap them into a list:
:param foo => [{name: 'Alice', age: 38, address: {city: 'London', residential: true}}]
Or you can use :params:
:params {foo: {name: 'Alice', age: 38, address: {city: 'London', residential: true}}}
In Neo4j Browser 3.5+ you can use
:params param_name => 'param_value'
The basic cases:
Set singe variable value mytext="Hello": :param mytext => "Hello"
set dictionary values attr={"oid":1, "text":"Hello"}:
:param attr => ({oid: 1, text:"Hello"})
Cypher usage:
MATCH (x) WHERE x.a = $mytext RETURN x
set a value MATCH (x) WHERE x.a = $attr.oid SET x.b = $attr.text
set multiple values MATCH (x) WHERE ... SET x = $attr

Rails using uniq_by method with nested records

I have a CollectionProxy of nested records:
#saved_videos = Video.all.is_saved
#sentences_to_extract = #saved_videos.map(&:sentences)
Each video has many sentences, and each sentence has one keyword, eg
[
[Video.id: 1,
sentences:
[Sentence.id: 1, keyword: 'hello'],
[Sentence.id: 2, keyword: 'friend']
],
[Video.id: 2,
sentences:
[Sentence.id: 3, keyword: 'hello'],
[Sentence.id: 4, keyword: 'mum']
]
]
When I try:
#sentences_to_extract.uniq_by(&:keyword)
it returns
undefined method `uniq_by' for #<Array:0x000001031f7968>
What is the best way to return a single collection of sentences with unique keywords, or in more general terms, to get a selection of nested records by a particular unique attribute?
With thanks to #ArupRakshit this is solved: I need to flatten the mapped arrays by one level, achieved in a one liner with flat_map.
Working code:
Video.all
.is_saved.flat_map(&:sentences)
.uniq { |s| s.keyword.downcase }

Is it possible to upsert documents in mondodb by an array of ids, so that each new created document's _id is the one from the array?

In my Rails project with mongodb, I retrieve user ids from twitter which I want to store in my User model. The plan is to upsert the collection of Users with the retrieved user ids I have in an array, and set every new created document _id to the corresponding user id from the array.
So when I do something like this:
Tweep.collection.find( _id: 1234567 ).modify( { "$set" => {a: true}, "$unset" => {c: ""} }, {upsert: true})enter code here
The result is like expected: <Tweep _id: 1234567, a(active): true, c(candidate_value): nil>
Now I want to do the same, but only passing an array of ids to upsert my collection on Users:
Tweep.collection.find(_id: {"$in" =>[123124,223553,6343643,23423]}, c: { "$exists" => true }).modify( { "$set" => {p: true}, "$inc" => {c: 1} }, {upsert: true})
The result is some newly created documents, but without the desired values as _id e.g. _id: 123124:
<Tweep _id: 5244501325fed0cfd2c1a615, a(active): nil, c(candidate_value): 1>
instead of:
<Tweep _id: 123124, a(active): nil, c(candidate_value): 1>
How can I make mongodb use the user id in my array to be the id for the field _id?
Any help is highly appreciated.
That is not possible. From the documentation:
If upsert is set to true and if no document matches the query
criteria, update() inserts a single document.
Then again, you write:
The result is some newly created documents
I hope that it's really only one document. With a query that contains only _id : {$in : [...]}, it wouldn't even insert a single document on my machine (MongoDB 2.5.0). It only inserts if I add more criteria. Could you check that again?
It's hard to come up with a meaningful definition of how this should behave. Combining $in can be tricky. Let's say you have two documents:
{ _id : 1, name : "John" }
{ _id : 2, name : "Jane" }
and you call
db.update({"_id" : {$in : [1,2]}, "name" : "Max"}, { ... }, { upsert: true});
What is supposed to happen? There is no document that has _id 1 or 2 and name equals "Max", so the upsert would have to insert... well, what? Maybe two documents with the name Max? If the array were larger, we'd create a ton of 'Max's which probably wasn't our intention (the semantics would be: "update one or insert a thousand", which is odd). So let's say we only insert one. But now, which _id to choose? And, of course, there is the problem that _id is a unique key, so in the example, both would fail.

Resources