I am developing an application using OrientDB as a database. The database is already filled, and now I need to make some queries to obtain specific information.
I have 3 classes and 3 edges to be concerned. What I need to do is query the database to see if some specific relationship exists. The relationship is like this:
ParlamentarVertex --Realiza> TransacaoVertex --FornecidaPor> EmpresaFornecedoraVertex AND ParlamentarVertex --SocioDe> EmpresaFornecedoraVertex
The names with a vertex in it are a vertex of course, and the arrows are the edges between the two vertexes.
I've tried to do this:
SELECT TxNomeParlamentar, SgPartido, SgUF FROM Parlamentar where ...
SELECT EXPAND( out('RealizaTransacao').out('FornecidaPor') ) FROM Parlamentar
But I do not know how to specify the relationships after the where clause.
I've also tried to use match
MATCH {class: Parlamentar, as: p} -Realiza-> {as:realiza}
But I am not sure how to specify the and clause that is really important for my query.
Does anyone have some tip, so I can go in the right direction?
Thanks in advance!
EDIT 1
I've managed to use the query below:
SELECT EXPAND( out('RealizaTransacao').out('FornecidaPor').in('SocioDe') ) FROM Parlamentar
It almost works, but return some relationships incorrectly. It looks like a join that I did not bind the Pk and FK.
The easiest thing here is to use a MATCH as follows:
MATCH
{class:ParlamentarVertex, as:p} -Realiza-> {class:TransacaoVertex, as:t}
-FornecidaPor-> {class:EmpresaFornecedoraVertex, as:e},
{as:p} -SocioDe-> {as:e}
RETURN p, p.TxNomeParlamentar, p.SgPartido, p.SgUF, t, e
(or RETURN whatever you need)
As you can see, the AND is represented as the addition of multiple patterns, separated by a comma
Related
Thank you for checking my question out!
I'm trying to write a query for a very specific problem we're having at my workplace and I can't seem to get my head around it.
Short version: I need to be able to target columns by their name, and more specifically by a part of their name that will be consistent throughout all the columns I need to combine or compare.
More details:
We have (for example), 5 different surveys. They have many questions each, but SOME of the questions are part of the same metric, and we need to create a generic field that keeps it. There's more background to the "why" of that, but it's pretty important for us at this point.
We were able to kind of solve this with either COALESCE() or CASE statements but the challenge is that, as more surveys/survey versions continue to grow, our vendor inevitably generates new columns for each survey and its questions.
Take this example, which is what we do currently and works well enough:
CASE
WHEN SURVEY_NAME = 'Service1' THEN SERV1_REC
WHEN SURVEY_NAME = 'Notice1' THEN FNOL1_REC
WHEN SURVEY_NAME = 'Status1' THEN STAT1_REC
WHEN SURVEY_NAME = 'Sales1' THEN SALE1_REC
WHEN SURVEY_NAME = 'Transfer1' THEN Null
ELSE Null
END REC
And also this alternative which works well:
COALESCE(SERV1_REC, FNOL1_REC, STAT1_REC, SALE1_REC) as REC
But as I mentioned, eventually we will have a "SALE2_REC" for example, and we'll need them BOTH on this same statement. I want to create something where having to come into the SQL and make changes isn't needed. Given that the columns will ALWAYS be named "something#_REC" for this specific metric, is there any way to achieve something like:
COALESCE(all columns named LIKE '%_REC') as REC
Bonus! Related, might be another way around this same problem:
Would there also be a way to achieve this?
SELECT (columns named LIKE '%_REC') FROM ...
Thank you very much in advance for all your time and attention.
-Kendall
Table and column information in Db2 are managed in the system catalog. The relevant views are SYSCAT.TABLES and SYSCAT.COLUMNS. You could write:
select colname, tabname from syscat.tables
where colname like some_expression
and syscat.tabname='MYTABLE
Note that the LIKE predicate supports expressions based on a variable or the result of a scalar function. So you could match it against some dynamic input.
Have you considered storing the more complicated properties in JSON or XML values? Db2 supports both and you can query those values with regular SQL statements.
I have some tables by day and by hour, called 2015_09_01_00, 2015_09_01_01..., 2015_09_02_00, 2015_09_02_01, etc.
I also created a virtual table for 2015_09_01, 2015_09_02, etc, aggregating them respectively by day.
So, in this context, when I want to query some virtual tables (some days) I have to execute this query for example:
SELECT fields FROM TABLE_QUERY(dataset, 'REGEXP_MATCH(table_id, r"(2015_09_01|2015_09_02)$")')
It gives network unreachable error, I guess is messing up between the original tables and the virtual ones since the names are related.
However, if I execute:
SELECT table_id FROM dataset.__TABLES_SUMMARY__ WHERE REGEXP_MATCH(table_id, r"(2015_09_01|2015_09_02)$")
2015_09_01
2015_09_02
it seems that the filter is created successfully.
So, what am I doing wrong here?
Thanks for your help in advance.
Above example worked for me.
Most likely in your dataset you have other tables with same pattern as you are trying to match.
Try to restrict your regex. For example as below
SELECT fields FROM TABLE_QUERY(dataset, 'REGEXP_MATCH(table_id, r"^(2015_09_01|2015_09_02)$")')
Did you define the daily views to reference themselves? Your use of $ suggested you were thinking about this, but to make sure -- they should reference only the hourly tables.
For example, if you named a view 2014_09_14 when it was based on a TABLE_QUERY for
'REGEXP_MATCH(table_id, r"2015_09_14")'
then it would reference itself, which does not work. (This ought to be a clearer error though.)
If you define the view with a TABLE_QUERY that can't match itself
'REGEXP_MATCH(table_id, r"2015_09_14_\d\d")'
then it should work. If you select your view's "Details" what is the query that defined it?
I have a Django application with a Publication model and a Tag model. Each publication has one or more Tags associated with it. I want to query the database with a set of two Tags and have returned only publications that have BOTH of those tags.
I cannot seem to find the syntax for this although I am certain it is readily available - I suppose I am not using the correct language to search. What I have tried already is:
pubs_for_tags = Publication.objects.filter(tags__title__istartswith=q, tags__title__istartswith=q2)
But this gives me an error "keyword argument repeated". I've also tried some variations of this, but nothing has worked so far. Can someone enlighten me on the correct syntax for this?
pubs_for_tags = Publication.objects.filter(tags__title__istartswith=q).filter( tags__title__istartswith=q2)
or
pubs_for_tags = Publication.objects.filter(Q(tags__title__istartswith=q), Q( tags__title__istartswith=q2))
I know this is old, but I just ran into the same problem and realized it points at an (as far as I know) undocumented aspect of using Django filters across one-to-many or many-to-many relations. Two conditions made within the same filter apply to the same related object. Two conditions made in separate filters can match two separate related objects.
Another way to think of this is that each complete filter only looks at a single related object at a time, removing a result if all of its related objects fail that filter. Given this, it is extremely rare that you would want two conditions in the same filter using the same keyword.
Consider the following query:
pubs_for_tags = Publication.objects.filter(
tags__title__istartswith=q,
tags__title__iendswith=q2
)
vs
pubs_for_tags = Publication.objects.filter(
tags__title__istartswith=q,
).filter(
tags__title__iendswith=q2
)
The first query finds publications that each have a single tag that both starts with q and ends with q2. When the keyword is the same (note I used two different keywords in my example), you also get the "keyword argument repeated" error.
The second query finds publications that each have a tag that starts with q and have a tag that ends with q2, but it can be two different tags for each publication. From your post, it sounds like this is very close to what you need (just change the "iendswith" to "istartswith"). The only part that could break is if q and q2 are the same or one is a substring of the other. In that instance, a publication could have a single tag that would satisfy both conditions.
Note that all this means using Q objects (which nnmware and Gaurav gave as a possible solution) will not give you the result you want. Having two Q objects in a single filter forces behaviour the same as the first example, but gets around the "keyword argument repeated" error.
pubs_for_tags = Publication.objects.filter(
Q(tags__title__istartswith=q) & Q(tags__title__istartswith=q2)
)
try this
from django.db.models import Q
pubs_for_tags = Publication.objects.filter(Q(tags__title__istartswith=q) & Q( tags__title__istartswith=q2))
check this link
In my project, we use solr to index a lot of different kind of documents, by example Books and Persons, with some common fields (like the name) and some type-specific fields (like the category, or the group people belong to).
We would like to do queries that can find both books and persons, with for each document type some filters applied. Something like:
find all Books and Persons with "Jean" in the name and/or content
but only Books from category "fiction" and "fantasy"
and only Persons from the group "pangolin"
everything sorted by score
A very simple way to do that would be:
q = name:jean content:jean
&
fq=
(type:book AND category:(fiction fantasy))
OR
(type:person AND group:pangolin)
But alas, as fq are cached, I'd prefer something allowing me simpler and so more reusable fq like :
fq=type:book,
fq=type:person,
fq=category(fiction fantasy),
fq=group:pangolin.
Is there a way to tell solr to merge or combine many queries? Something like 'grouping' fq together.
I read a bit about nested queries with _query_, but the very few documentation about it makes me think it's not the solution I'm looking for.
As Geert-Jan mentioned it in his answer, the possibility to do OR between fq is a solr asking feature, but with very little support by now: https://issues.apache.org/jira/browse/SOLR-1223
So I managed to simulate what I want to in a simple way:
for each field a document type can have, we have to define everytime a value (so if in my own example Books can have no category, at index time we still have to define something like category=noCategoryCode
when using a filter on one of this fields in a query on multiple types, we add a non-present condition in the filter, so fq=category:fiction becomes fq=category:fiction (*:* AND -category:*)
By this way, all other types (like Person) will pass through this filter, and the filter stands quite atomic and often used - so caching is still useful.
So, my full example becomes:
q = name:jean content:jean
&
fq= type:(book person)
&
fq= category:(fiction fantasy) (*:* AND -category:*)
&
fq= group:(pangolin) (*:* AND -group:*)
Still, can't wait SOLR-1223 to be patched :)
You can apply multiple filter queries at the same time
q=name:jean content:jean&fq=type:book&fq=type:person&fq=category(fiction fantasy)&fq=group:pangolin
Perhaps I am not understanding your issue, but the only difference between a query and a filter is that the filter is cached. If you don't care about the caching, just modify their query:
real query +((type:book category:fiction) (type:person group:pangolin))
Suppose that two tables exist: users and groups.
How does one provide "simple search" in which a user enters text and results contain both users and groups whose names contain the text?
The result of the search must distinguish between the two types.
The trick is to combine a UNION with a literal string to determine the type of 'object' returned. In most (?) cases, UNION ALL will be more efficient, and should be used unless duplicates are required in the sub-queries. The following pattern should suffice:
SELECT "group" type, name
FROM groups
WHERE name LIKE "%$text%"
UNION ALL
SELECT "user" type, name
FROM users
WHERE name LIKE "%$text%"
NOTE: I've added the answer myself, because I came across this problem yesterday, couldn't find a good solution, and used this method. If someone has a better approach, please feel free to add it.
If you use "UNION ALL" then the db doesn't try to remove duplicates - you won't have duplicates between the two queries anyway (since the first column is different), so UNION ALL will be faster.
(I assume that you don't have duplicates inside each query that you want to remove)
Using LIKE will cause a number of problems as it will require a table scan every single time when the LIKE comparator starts with a %. This forces SQL to check every single row and work it's way, byte by byte, through the string you are using for comparison. While this may be fine when you start, it quickly causes scaling issues.
A better way to handle this is using Full Text Search. While this would be a more complex option, it will provide you with better results for very large databases. Then you can use a functioning version of the example Bobby Jack gave you to UNION ALL your two result sets together and display the results.
I would suggest another addition
SELECT "group" type, name
FROM groups
WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
SELECT "user" type, name
FROM users
WHERE UPPER(name) LIKE UPPER("%$text%")
You could convert $text to upper case first or do just do it in the query. This way you get a case insensitive search.