Can a nested N-quad-star have multiple graph labels? - ontology

Can a nested N-quad-star have quoted quads in it which have a different graph_labels?
For example -
Lets say we have a nested N-quad-star as ->
<< << :subject_1 :predicate_1 :object_1 :graph_1 >> :predicate_2 :object_2 :graph_2 >>
Is it possible to have to have graph_1 and graph_2 as different graphs? If Yes, then how can the above statement be broken down into simpler non nested n-quads statements?
I tried looking for grammar in these documentations - n-quad-star and n-quad. But i am unable to understand -
Whether or not different graphs are allowed?
How to break down a nested n-quad-star statement into simpler non nested n-triple or n-quad statement?

Related

Postgresql text searching, matching multiple words

I don't know the name for this kind of search, but I see that it's getting pretty common.
Let's say I have records with the following file names:
'order_spec.rb', 'order.sass', 'orders_controller_spec.rb'
If I search with the following string 'oc' I would like the result to return 'orders_controller_spec.rb' due to match the o in orders and the c in controller.
If the string is 'os' then I'd like all 3 to match, 'order_spec.rb', 'order.sass', 'orders_controller_spec.rb'.
If the string is 'oco' then I'd like 'orders_controller_spec.rb'
What is the name for this kind of search and how would I go about getting this done in Postgresql?
This is a called a subsequence search. One simple way to do it in Postgres is to use the LIKE operator (or several of the other options in those docs) and fill the spaces between your letters with a wildcard, which for LIKE is %. To match anything with an o followed by an s in the words column, that would look like this:
SELECT * FROM table WHERE words LIKE '%o%s%';
This is a relatively expensive search, but you can improve performance with a varchar_pattern_ops or text_pattern_ops index to support faster pattern matching.
CREATE INDEX pattern_index ON table (words varchar_pattern_ops);

Adding line breaks into procs with nested each iterators ruby

Hey guys I'm learning Ruby and trying to connect it to PostgreSQL database in my computer. I have the connection and two tables created one with two tuples. I want to display the values of each tuple in its own line but add a line break '\n' between tuples.
I've been trying to apply my knowledge of Procs and figure out a way of making the queries reusable and thought Procs was a good idea although it would like a bit messy to some of you. You are free and welcome to criticize my code
res = conn.exec("select * from one.employees") #The table with the tuples as Hashes
iter=Proc.new do
|tuple| tuple.map{|tupleVals| tupleVals}
end #This goes over each tuple
stripTuples2=Proc.new do |hash| #a is a Hash containing all the tuples.
hash.each do
|tuple| tuple.each{|str| puts "#{str[0]}: #{str[1].strip}"}.to_s+"\n"
end
end #End of stripTuples2
That's the structure and I call it like this
stripTuples2.call(iter.call(res))
Although it prints all the values, each one in a new line it omits the "\n" I added in the code, it was the only place It let me do it without trowing an error. What can I do to fix this or to make my code better?

Chaining multiple instances of the same named scope

I've got a Rails app with models called Item, ItemTag, and Tag. Items have many Tags through ItemTags. The associations are working correctly.
I want to build a search interface for Items that allows filtering by multiple Tags. I have a bunch of named scopes for various conditions, and they chain without problems. I figure I'll build the query based on user input. So I made a scope that returns the set of Items that has a given tag:
scope :has_tag, -> (tag_id) { joins(:tags).where(tags: {id: tag_id}) }
It works!
> Item.has_tag(73).count
=> 6
> Item.has_tag(81).count
=> 5
But:
> Item.has_tag(73).has_tag(81).count
=> 0
There are two items that have both tags, but chaining the scopes together produces the following SQL, which is always going to return empty, for obvious reasons; it's looking for a tag that has two ids, rather than an item that has two tags.
SELECT [items].*
FROM [items]
INNER JOIN [item_tags] ON [item_tags].[item_id] = [items].[id]
INNER JOIN [tags] ON [tags].[id] = [item_tags].[tag_id]
WHERE [tags].[id] = 81 AND [tags].[id] = 73
I know I can get the intersection of the collections after they're returned, but this seems inefficient, so I'm wondering if there is a standard practice here. (It seems like a common task.)
> (Item.has_tag(73) & Item.has_tag(81)).count
=> 2
Is there a way to write the scope to make this work, or will this need to be done another way?
I think the input tags need to be processed as an array, not chained. With this statement, you're getting a subset under tag(83) of tag(71), which is not what you want. The query confirms this.
Item.has_tag(73).has_tag(81).count
You might try a scope that processes the tags as an array and then constructs the query using lambda
scope :has_tags, lambda { |tag_ids| includes(:tag_ids)
.where("tag_id IN (?)", tag_ids.collect { |tag_id| } )
.group('"items"."id"')
.having('COUNT(DISTINCT "tag_ids"."id") = ?', tag_ids.count) }
I don't have full knowledge of your model relationship setups, etc, and I'm the typo queen, so the snippet above may or may not work out of the box, but I think the information here is that yes, you can process a set of tags in a single scope and query once to get a collection.

Cypher Query combining results that can be ordered as a whole

I have a Cypher query that combines two result sets that I would like to then order as a combined result.
An example of what I am trying to do is here: http://console.neo4j.org/r/j2sotz
Which gives the error:
Cached(nf of type Collection) expected to be of type Map but it is of type Collection - maybe aggregation removed it?
Is there a way to collect multiple results into a single result that can be paged, ordered, etc?
There are many posts about combining results, but I can't find any that allow them to be treated as a map.
Thanks for any help.
You can collect into a single result like this:
Start n=node(1)match n-[r]->m
with m.name? as outf, n
match n<-[r]-m
with m.name? as inf, outf
return collect(outf) + collect(inf) as f
Unions are covered here: https://github.com/neo4j/neo4j/issues/125 (not available right now).
I haven't seen anything about specifically sorting a collection.

Rails: A good search algorithm

I'm trying to return results more like the search
My curren algorithm is this
def search_conditions(column, q)
vars = []
vars2 = []
vars << q
if q.size > 3
(q.size-2).times do |i|
vars2 << q[i..(i+2)]
next if i == 0
vars << q[i..-1]
vars << q[0..(q.size-1-i)]
vars << q[i % 2 == 0 ? (i/2)..(q.size-(i/2)) : (i/2)..(q.size-1-(i/2))] if i > 1
end
end
query = "#{column} ILIKE ?"
vars = (vars+vars2).uniq
return [vars.map { query }.join(' OR ')] + vars.map { |x| "%#{x}%" }
end
If I search for "Ruby on Rails" it will make 4 search ways.
1) Removing the left letters "uby on Rails".."ils"
2) Removing the right letters "Ruby on Rail".."Rub"
3) Removing left and right letters "uby on Rails", "uby on Rail" ... "on "
4) Using only 3 letters "Rub", "uby", "by ", "y o", " on" ... "ils"
Is good to use these 4 ways? There any more?
Why are you removing these letters? Are you trying to make sure that if someone searches for 'widgets', you will also match 'widget'?
If so, what you are trying to do is called 'stemming', and it is really much more complicated than removing leading and trailing letters. You may also be interested in removing 'stop words' from your query. These are those extremely common words that are necessary to form grammatically-correct sentences, but are not very useful for search, such as 'a', 'the', etc.
Getting search right is an immensely complex and difficult problem. I would suggest that you don't try to solve it yourself, and instead focus on the core purpose of your site. Perhaps you can leverage the search functionality from the Lucene project in your code. This link may also be helpful for using Lucene in Ruby on Rails.
I hope that helps; I realize that I sort of side-stepped your original question, but I really would not recommend trying to tackle this yourself.
As pkaeding says, stemming is far too complicated to try to implement yourself. However, if you want to search for similar (not exact) strings in MySQL, and your user search terms are very close to the full value of a database field (ie, you're not searching a large body of text for a word or phrase), you might want to try using the Levenshtein distance. Here is a MySQL implementation.
The Levenshtein algorithm will allow you to do "fuzzy" matching, give you a similarity score, and help you avoid installation and configuration of a search daemon, which is complicated. However, this is really only for a very specific case, not a general site search.
While, were all suggesting other possible solutions, check out:
Sphinx - How do you implement full-text search for that 10+ million row table, keep up with the load, and stay relevant? Sphinx is good at those kinds of riddles.
Thinking Sphinx - A Ruby connector between Sphinx and ActiveRecord.

Resources