Given a Model with columns a and b, I want to get three records where a and b are a: 0 b: 3, a: 1 b: 4, and a: 2 b: 5.
The following way of retrieving records would result in issuing the query three times.
as = [0,1,2]
bs = [3,4,5]
Model.where(a: as[0], b: bs[0])
Model.where(a: as[1], b: bs[1])
Model.where(a: as[2], b: bs[2])
To make one query, I need to write the following.
Model.where(a: as[0], b: bs[0]).or(Model.where(a: as[1], b: bs[1])).or(Model.where(a: as[2], b: bs[2]))
In the above example, the number of records to be retrieved was fixed to 3. Is there any way to retrieve a group of records in a single query execution when the number of records to be retrieved is arbitrary N (the number of elements in as and bs is N)?
The way I can think of is to generate a query with a string, but I would like to achieve this with rails built-in functionality as much as possible.
Just fold the criteria list into an AR query using #reduce, something like
criteria_list = [
{a: 1, b: 2},
{a: 2, b: 3},
{a: 3, b: 4},
]
criteria_list.reduce(Model.none) do |scope, criteria|
scope.or(Model.where(**criteria))
end
(just but be careful - the resulted query might be very inefficient, depending on the criteria set)
Related
I am trying add some test data to all of my nodes of type A. I want to use a json file which contains that dummy data:
[
{
a: "x",
b: 1,
c: 3
},
{
a: "y",
b: 5,
c: 4
},
...
]
For every node of type A, all these objects should become one node of type B. They should also have a relationship.
So I tried it like this using apoc.periodic.iterate (because I have millions of nodes) and apoc.load.json:
CALL apoc.periodic.iterate(
'MATCH (n:A) RETURN n',
'CALL apoc.load.json("file:///values.json") YIELD value
WITH value
FOREACH (m in value |
CREATE (v:B { a: m.a, b: m.b, c: m.c })
MERGE (n)-[r:REL]->(v)',
{batchSize:500})
YIELD batches, total
RETURN batches, total
However this did nothing at all.
I also tried to load the json outside of iterate, so I dont have to read it for each node, but I could not find a way to use it inside then.
How could I get this to work?
Edit:
This is another query I tried:
CALL apoc.load.json("file:///values.json") YIELD value
WITH value AS value
CALL apoc.periodic.iterate('MATCH (n:A) RETURN n', 'FOREACH(m in $value | CREATE (v:B {a:m.a, b: m.b, c: m.c}) MERGE (n)-[r:REL]->(v))', {batchSize:500}) YIELD batches, total
RETURN batches, total
While running I tried checking if something happens using MATCH (n:A)-[]-(v:B) RETURN n, v LIMIT 100 but it seems that nothing is being updated.
This is what it should look like (red node = type A):
Specifically, does the Flatten PTransform in Beam perform any sort of:
Deduplication
Filtering
Purging of existing elements
Or does it just "merge" two different PCollections?
The Flatten transform does not do any sort of deduplication, or filtering of any kind. As mentioned, it simply merges the multiple PCollections into one that contains the elements of each of the inputs.
This means that:
with beam.Pipeline() as p:
c1 = p | "Branch1" >> beam.Create([1, 2, 3, 4])
c2 = p | "Branch2" >> beam.Create([4, 4, 5, 6])
result = (c1, c2) | beam.Flatten()
In this case, the result PCollection contains the following elements: [1, 2, 3, 4, 4, 4, 5, 6].
Note how the element 4 appears once in c1, and twice in c2. This is not deduplicated, filtered or removed in any way.
As a curious fact about Flatten, some runners optimize it away, and simply add the downstream transform in both branches. So, in short, no special filtering or dedups. Simply merging of PCollections.
MATCH (c:someNode) WHERE LOWER(c.erpId) contains (LOWER("1"))
OR LOWER(c.constructionYear) contains (LOWER("1"))
OR LOWER(c.label) contains (LOWER("1"))
OR LOWER(c.name) contains (LOWER("1"))
OR LOWER(c.description) contains (LOWER("1"))with collect(distinct c) as rows, count(c) as total
MATCH (c:someNode)-[adtype:OFFICIAL_someNode_ADDRESS]->(ad:anotherObject)
WHERE toString(ad.streetAddress) contains "1"
OR toString(ad.postalCity) contains "1"
with distinct rows+collect( c) as rows, count(c) +total as total
UNWIND rows AS part
RETURN part order by part.name SKIP 20 Limit 20
When I run the following cypher query it returns duplicate results. Also it the skip does not seem to work. What am I doing worng
When you use WITH DISTINCT a, b, c (or RETURN DISTINCT a, b, c), that just means that you want each resulting record ({a: ..., b: ..., c: ...}) to be distinct -- it does not affect in any way the contents of any lists that may be part of a, b, or c.
Below is a simplified query that might work for you. It does not use the LOWER() and TOSTRING() functions at all, as they appear to be superfluous. It also only uses a single MATCH/WHERE pair to find all the the nodes of interest. The pattern comprehension syntax is used as part of the WHERE clause to get a non-empty list of true value(s) iff there are any anotherObject node(s) of interest. Notice that DISTINCT is not needed.
MATCH (c:someNode)
WHERE
ANY(
x IN [c.erpId, c.constructionYear, c.label, c.name, c.description]
WHERE x CONTAINS "1") OR
[(c)-[:OFFICIAL_someNode_ADDRESS]->(ad:anotherObject)
WHERE ad.streetAddress CONTAINS "1" OR ad.postalCity CONTAINS "1"
| true][0]
RETURN c AS part
ORDER BY part.name SKIP 20 LIMIT 20;
We have a bunch of nodes with properties that are converted from BigDecimals to string during insert and vice versa during load.
This leads to typical problems during sorting. Values 1, 2, 3, 10 get sorted as 1, 10, 2, 3.
Does cypher has any means of doring natural sorting on strings? Or do we have to convert these properties to doubles or something like that?
Guess the best way is to store them as integers in your db. Also, in the current milestone release, there's a toInt() function which you could use to sort.
START n=node(*)
WITH toInt(n.stringValue) as nbr
RETURN n
ORDER BY nbr
Can you add a primary sort on string length?
CREATE ({val:"3"}),({val:"6"}),({val:"9"}),({val:"12"}),({val:"15"}),({val:"18"}),({val:"21"})
MATCH (n) RETURN n.val ORDER BY n.val
// 12, 15, 18, 21, 3, 6, 9
MATCH (n) RETURN length(n.val), n.val
// 3, 6, 9, 12, 15, 21
http://console.neo4j.org/r/kb0obm
If you keep converting them back and forth it sounds like it would be better to store them as their proper types in the database.
I notice Solr 4.0 has introduced 'join' feature for documents having relationships. this is great, however, I notice examples given by http://wiki.apache.org/solr/Join are for single core which all documents are in single index.
Does anybody know if I can use 'join' for multiple core?
This comment says it's possible by using:
{!join from=fromField to=toField fromIndex=fromCoreName}fromQuery
I tried it myself, and here's a more detailed example:
Have two cores
brands {id,name}
products {id, name, brand_id}
BRANDS: {1, Apple}, {2, Samsung}, {3, HTC}
PRODUCTS: {1, iPhone, 1}, {2, iPad, 1}, {3, Galaxy S3, 2}, {4, Galaxy Note, 2}, {5, One X, 3}
http://example.com:8999/solr/brands/select?q=*:*&fq={!join from=brand_id to=id fromIndex=products}name:iPad
This translates to something like:
SELECT b.* FROM brands b
INNER JOIN products p ON b.id=p.brand_id
WHERE p.name="iPad";
Result will be: {id: "1", name:"Apple"}