Select Multiple Columns with Flux - influxdb

My data looks something like this --
I want to create a FLUX query which results into --
SELECT UUID, CUST_ID, PO_NO, TIMESTAMP FROM CUST_PO_DTLS WHERE PO_NO = ?
In my Influx DB bucket, UUID, CUST_ID, PO_NO are all fields.
Here, I explicitly mention the columns and need those columns for further processing.
So far, I could not find a way to select all fields but filter with one fields.
Here is my flux query --
import "influxdata/influxdb/schema"
from(bucket: "sap")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) =>
r._measurement == "cpd"
)
|> filter(fn: (r) => r["_field"] =~ /^(UUID|CUST_ID|PO_NO| STATUS)$/)
|> filter(fn: (r) => r["_value"] =="PO_1")
|> schema.fieldsAsCols()
However, I only get 1 column returned with above query (PO_NO).
How do I still get the remaining columns for my processing ?

|> filter(fn: (r) => r["_field"] =~ /^(UUID|CUST_ID|PO_NO| STATUS)$/)
|> filter(fn: (r) => r["_value"] =="PO_1")
These two lines are self-conflicting. It's trying to have 4 specified fields in the resultset but the next line restricts the field has to be "PO_NO" because only field "PO_NO" has the value of "PO_1".
You might need to modify the schema a little bit. That is, move "PO_NO" from field into tag.
New query could be:
import "influxdata/influxdb/schema"
from(bucket: "sap")
|> range(start: v.timeRangeStart, stop:v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "cpd")
|> filter(fn: (r) => r.PO_NO== "PO_1")
|> filter(fn: (r) => r["_field"] =~ /^(UUID|CUST_ID|STATUS)$/)
|> schema.fieldsAsCols()
btw, looks like you are using InfluxDB for traditional Purchase Order query. This might not be the best database for you as InfluxDB deals with the time-series data the best. Why not just use traditional RDBMS?

Related

How do I choose to create a node based on whether it exists in the database in neo4j?

I tried the following but it threw this error. I wish to only create a new person node if there isnt a person node in the existing database that has the exact same properties.
org.neo4j.driver.exceptions.ClientException: Invalid input 'R': expected
MERGE (n:Person{id: abc.id})
MERGE (m:Place{place:def.id})
MERGE (o:Thing{id:abcd.id})
WITH n,m,o
OPTIONAL MATCH (n) – [:present_at] -> x with n,m,o, collect (distinct x) as known_place
OPTIONAL MATCH (m) – [:is] -> y with n,m,o, collect (distinct y) as known_thing
FOREACH (a in ( CASE WHEN NOT m IN known_place THEN [1] ELSE [] END ) CREATE (n)-[:present_at] ->(m))
FOREACH (a in ( CASE WHEN NOT o IN known_thing THEN [1] ELSE [] END ) CREATE (m)-[:is] ->(o))
That error was caused by a missing | in each of your FOREACH clauses. For example, this would fix that syntax error:
FOREACH (a in ( CASE WHEN NOT m IN known_place THEN [1] ELSE [] END ) | CREATE (n)-[:present_at] ->(m))
FOREACH (a in ( CASE WHEN NOT o IN known_thing THEN [1] ELSE [] END ) | CREATE (m)-[:is] ->(o))
However, your query would still have numerous other syntax errors.
In fact, the entire query could be refactored to be simpler and more efficient:
WITH {id: 123} AS abc, {id: 234} as def, {id: 345} AS abcd
MERGE (n:Person{id: abc.id})
MERGE (m:Place{place: def.id})
MERGE (o:Thing{id: abcd.id})
FOREACH (a in ( CASE WHEN NOT EXISTS((n)–[:present_at]->(m)) THEN [1] END ) | CREATE (n)-[:present_at]->(m))
FOREACH (a in ( CASE WHEN NOT EXISTS((m)–[:is]->(o)) THEN [1] END ) | CREATE (m)-[:is]->(o))

mongoid 4 wrong number of arguments (3 for 1) for scope

I trying to create the following scope:
scope :involving, -> (user) do
where("conversations.sender_id =? OR conversations.recipient_id =?", user.id, user.id)
end
but I get:
wrong number of arguments (3 for 1)
What I'm doing wrong.
Thanks in advance.
Mongoid's where doesn't understand SQL snippets like a = ? OR b = ?, it only wants a single hash argument. Hence your "3 for 1" error.
You want to use any_of to build an :$or query:
any_of(
{ :sender_id => user.id },
{ :recipient_id => user.id }
)
Beware that multiple any_ofs are combined so this:
M.any_of(a, b).any_of(c, d)
is saying:
a OR b OR c OR d # any_of(a, b, c, d)
rather than
(a OR b) AND (c OR d)
as you might expect.
If you're expecting to every combine OR conditions then you might want to combine the sender_id and recipient_id into a single array field:
field :involved_ids, :type => Array
so that you could say:
where(:involved_ids => user.id)
and avoid the OR-problem. You'd still have separate sender_id and recipient_id fields of course, you'd just duplicate the data to better fit your queries. Denormalizing your data to suit your queries is quite common with MongoDB.

How To Use OR Operator In Where Condition-Rails ActiveRecord

Can someone help me that how to use OR operator in where condition in ActiveRecord in Rails.
I want like below,
x=[1,2,3]
y=['a','b','c']
Z.where(:name => y OR :val => x)
Here in table Z we have two fields called name and val. And i need to fetch those record where name in ('a','b','c') OR val in (1,2,3).
You can do this with the String argument to where.
Z.where('name IN (?) OR val IN (?)', y, x)
Using this parameterized format, y and x will be sanitized automatically.

Nested increasing foreach loop

What is the idiomatic way to get something like that?
((fn [coll] (function-body)) [:a :b :c :d])
-> [[:a :b][:a :c][:a :d][:b :c][:b :d][:c :d]]
I can only do this in this way.
#(for [i (range (count %))
j (range (inc i) (count %))]
[(nth % i) (nth % j)])
But this is ugly, and at bigger collections very slow. I would like to avoid a loop/recur
Using recursion explicitly ...
(defn pairs [coll]
(if-let [[x & xs] (seq coll)]
(lazy-cat (map #(vector x %) xs) (pairs xs))))
For example,
(pairs [:a :b :c :d])
; ([:a :b] [:a :c] [:a :d] [:b :c] [:b :d] [:c :d])
This is a lazy sequence. You can use vec to pour it into a vector if need be: a decision better left to the client, I think.
Here's a lazy solution.
user> (def data [:a :b :c :d])
#'user/data
user> (defn loopy [data]
(lazy-seq (if (seq data)
(cons (map #(vector (first data) %) (rest data))
(loopy (rest data)))
nil)))
#'user/loopy
user> (apply concat (loopy data))
([:a :b] [:a :c] [:a :d] [:b :c] [:b :d] [:c :d])
this produces a lazy sequence where each element it a lazy sequence of creating a vector of the current element into a vector with each of the rest of the elements. The next segment is generated lazily when this segment is empty by the call to (apply concat ).
This is along the lines of Juan Manuel's answer, I find it a bit more readable using list comprehension for the last part. The anonymous function generates the pairs [(first s) x]l for all the elements in (rest s).
(defn pairs [xs]
(->> xs
(iterate rest)
(take-while seq)
(mapcat #(for [x (rest %)]
[(first %) x]))))
I've found an ugly pipeline that solves the problem. I don't find it much elegant but I haven't been able to beautify it.
(->> [:a :b :c :d]
(iterate rest)
(take-while not-empty)
(mapcat (fn [[f & r]] (map #(vector f %) r)))
vec)
Let's analyze the function in the mapcat when given list [:a :b :c :d]. It computes all vectors with first element :a and second element succesive elements taken from [:b :c :d], that is([:a :b] [:a :c] [:a :d])`.
The first part of the pipeline, constructs the sequence of all the rests od the original vector ([:a :b :c :d](:b :c :d)(:c :d)(:d) () () () ...) which is stopped at the first empty rest.
Then the mapcat plugs this list in the combining function described before, and the vec at the end, converts the sequence into a vector.
This can be more readable by introducing some auxiliar functions:
(defn rests [coll]
(take-while not-empty (iterate rest coll)))
(defn pairfirst [[f & r]]
(map #(vector f %) r))
(defn pairs [coll]
(mapcat pairfirst (rests coll)))
for is already lazy, and filter is too. So one way to do this, if the elements have a natural order, is to produce the cartesian product, and then filter on sort order.
(defn pairs [c]
(->> (for [x c, y c] [x y])
(filter #(apply <= %))))
(def c (range 0 1e7))
(time (nth (pairs c) 0)) ;; ~ 0.07 ms
(time (nth (pairs c) 1e4)) ;; ~ 6 ms
(time (nth (pairs c) 1e7)) ;; ~ 2600 ms
I think your use of nth might be slowing the collection iteration down:
(def pairs2
#(for [i (range (count %))
j (range (inc i) (count %))]
[(nth % i) (nth % j)]))
(def c (range 0 1e7))
(time (nth (pairs2 c) 0)) ;; ~ 960 ms
(time (nth (pairs2 c) 1e4)) ;; ~ 1514 ms
(time (nth (pairs2 c) 1e7)) ;; ~ ¯\_(ツ)_/¯

How to implement a search query in NHibernate 3 (using NHibernate.Linq)

I'm trying to build a search query using NHibernate that will filter on parameters from several different tables and result in somewhat-reasonable SQL that can take advantage of NHibernate's lazy-loading.
Fromm reading various tips online, it seems that the latest-and-greatest way to do that is to use the QueryOver object to conditionally add in the parameters being used, as in the following snippet:
Hibernate.Criterion.QueryOver<Models.Site, Models.Site> query = NHibernate.Criterion.QueryOver.Of<Models.Site>();
if (!string.IsNullOrEmpty(state))
query = query.WhereRestrictionOn(r => r.State.StateName).IsInsensitiveLike("%" + state + "%");
if (startDate.HasValue)
query = query.Where(r => r.Events
.Where(e=>e.EventDate >= startDate.Value)
.Count() > 0
);
return query.GetExecutableQueryOver(currentSession).Cacheable().List();
(an event has a foreign-key to site)
I have two questions:
How do I filter the child objects, instead of just the parent? The sample code above gives me all the sites with a matching events, but within that site, I only want matching events. If I'm supposed to use a join or a subquery, how? I'm confused about maintaining my tree-like hierarchy with lazy-loading through a join or subquery.
Edit: this has been answered. Thanks psousa!
How do I add an or clause? I found reference to a Disjunction object, but it doesn't seem like that's available using the QueryOver method.
Edit:
I want to result in a list of sites (top level object) filtered by the site criteria, and each site should have its list of events filtered by the event criteria.
I expect it to generate SQL like the following:
SELECT *
FROM [site] s
LEFT JOIN [event] e ON s.siteID = e.siteID
WHERE e.eventDate > #eventDate
AND (s.stateCd = #state OR s.stateName LIKE #state)
I would do that query as such:
//use aliases. Optional but more practical IMHO
Site siteAlias = null;
Event eventAlias = null;
//use JoinAlias instead of JoinQueryOver to keep the condition at the "Site" level
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.List();
You mentioned the Disjunction class, and it may in fact be used with QueryOver, like:
var disjunction= new Disjunction();
disjunction.Add(() => siteAlias.StateCD == state);
disjunction.Add(Restrictions.On(() => siteAlias.StateName).IsLike(state));
The QueryOver query would be:
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(disjunction)
.List();
When using a join alias as suggested by psousa, you will get results in a strange combination of an object structure and a row structure, with the top-level objects being duplicated by the child objects that are attached to them. In order to get the results I was looking for, you can use TransformUsing and a DistinctRootEntityResultTransformer as shown in the following code:
Site siteAlias = null;
Event eventAlias = null;
var results = currentSession.QueryOver<Site>(() => siteAlias)
.JoinAlias(m => m.Event, () => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.TransformUsing(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List();

Resources