Thanks to ModelChangedListener, I can monitor changes in a Model as explained in Jena documentation (Event handling in Jena).
Model m = ModelFactory.createDefaultModel();
ModelChangedListener L = new MyListener();
m.register(L);
However, in my project, I want to monitor a Dataset for changes to run a code after something occurred in the default graph or one of the named graphes of the Dataset.
What I want to do is simply triggering events after executing such a query against a Dataset:
PREFIX d: <http://learningsparql.com/ns/data#>
PREFIX dm: <http://learningsparql.com/ns/demo#>
INSERT DATA
{
d:x dm:tag "one" .
d:x dm:tag "two" .
GRAPH d:g1
{
d:x dm:tag "three" .
d:x dm:tag "four" .
}
}
to detect that "one" "two" were added to the default graph, and "three" "four" where added to g1.
With this code, I can't even detect changes happening in the default graph of the Dataset, let alone detecting changes in named graphs.
Dataset ds = RDFDataMgr.loadDataset(ONTOLOGY_PATH);
Model defaultModel = ds.getDefaultModel();
ModelChangedListener modelChangedListener = new MyListener();
defaultModel.register(modelChangedListener);
Take a look at DatasetGraphMonitor which takes a DatasetChanges for processing changes.
Listening to models is unreliable if it works at all because the changes may be going straight to the dataset. A DatasetFactory.createGeneral data should work for models added by the application but in your example d:g1 may not. You would have to add a way to create the model. The engine for this is DatasetGraphMapLink.
But DatasetGraphMonitor / DatasetChanges is easier.
An alternative is RDF Delta, and DatasetGraphChanges where the changes are delivered with transaction boundaries.
Related
To explain my problem I use this example data set:
SampleID Date Project Problem
03D00173 03-Dec-2010 1,00
03D00173 03-Dec-2010 1,00
03D00173 28-Sep-2009 YNTRAD
03D00173 28-Sep-2009 YNTRAD
Now, the problem is that I need to replace the text "YNTRAD" with "YNTRAD_PILOT" but only for the cases with Date = 28-Sep-2009.
This is example is part of a much larger database, with many more cases having Project=YNTRAD and Data=28-Sep-2009, so I can not simply select first all cases with 28-Sep-2009, then check which of these cases have Project=YNTRAD and then replace. Instead, what I need to do is:
Look at each case that has a 1,00 in Problem (these are problem
cases)
Then find the SampleID that corresponds with that sample
Then find all other cases with the same SampleID BUT WITH
Date=28-Sep-2009 (this is needed because only those samples are part
of a pilot study) and then replace YNTRAD in Project to
YNTRAD_PILOT.
I read a lot about:
LOOP
- DO REPEAT
- DO IF
but I don't know how to use these in solving this problem.
I first tried making a list containing only the sample ID's that need eventually to be changed (again, this is part of a much larger database).
STRING SampleID2 (A20).
IF (Problem=1) SampleID2=SampleID.
EXECUTE.
AGGREGATE
/OUTFILE=*
/BREAK=SampleID2
/n_SampleID2=N.
This gives a dataset with only the SampleID's for which a change should be made. However I don't know how to read out this dataset case by case and looking up each SampleID in the overall file with all the date and then change only those cases were Date = 28-Sep-2009.
It sounds like once we can identify the IDs that need to be changed we've done the tricky part here. We can use AGGREGATE with MODE=ADDVARIABLES to add a problem Id counter variable to our dataset. From there, it's as you'd expect.
* Add var IdProblemCnt to your database . Stores # of times a given Id had a record with Problem = 1.
AGGREGATE
/OUTFILE=* MODE=ADDVARIABLES
/BREAK=SampleId
/IdProblemCnt=CIN(Problem, 1, 1) .
EXE .
* once we've identified the "problem" Ids we can use `RECODE` Project var.
DO IF (IdProblemCnt>0 AND Date = DATE.MDY(9,28,2009) .
RECODE Project ('YNTRAD' = 'YNTRAD_PILOT') .
END IF .
EXE .
I've been making a game with the LOVE2D game engine, and I've stumbled across an issue. I want to access a variable inside a nested table, but I don't know how.
Here's my code right now:
local roomNum = 1
local rooms = { r1 = { complete = false, name = "Room 1" }
if rooms[roomNum].complete == true then --problematic line
--do stuff
end
If I replace rooms[roomNum].complete with rooms.r1.complete then it works.
Any help would be appreciated!
'http://lua-users.org/wiki/TablesTutorial'
The provided link gives easy to understand examples on tables in Lua, so it may prove a useful resource in the future.
As for the why the replacement code worked, a dictionary is just sets of key/value pairs (kvp) . In examples from other languages, these pairs are normally shown as something like KeyValuePair.
In your case, you are using a variation on how dictionaries are used. As you have seen, you can use numbered indexes like room[1], or you can use a string like room["kitchen"]. It gets interesting when you provide a set of data to initialize the dictionary.
Building off of the provided data, you have the following:
local rooms = { r1 = { complete = false, name = "Room 1" }
r1 is equivalent to using rooms["r1"] without the dataset. In providing the dataset, any "named" Key can be referenced like it is a property of the dictionary (think of classes with public getter/setter). For the named keys of a dataset, you can provide a key as numbers as well.
local rooms = { [1] = { complete = false, name = "Room 1" }
This indexing fits the direction you were headed on providing a room index. So, you could either swap the dataset to use integers instead of r1, r2 and so on, or you could concatenate r and the index numbering. That is pretty much up to you. Keep in mind as you go further down nesting the same rules apply. So, complete could look like rooms[1].complete, rooms["r1" ].complete, or rooms.r1.complete.
I have datasets like this:
C:\temp\SalesFigures FY13.dta
C:\temp\SalesFigures FY14.dta
C:\temp\SalesFigures FY15.dta
etc.
Each file contains sales data from 50 states. I often need to run a block of code for just some of the states in these files. I specify those states in a file called StatesToRun.dta (e.g., AK, CA, WA) and use a foreach command to loop through each state. I also use a macro to specify the FY .dta file I want to use.
For example:
* Specify file to run.
local FY "FY14"
* Run code only for the states I list in StatesToRun.dta.
use "C:/temp/StatesToRun.dta", clear
levelsof state, local(statelist)
foreach MyState of local statelist
{
use "C:/temp/SalesFigures 'FY'.dta", clear
keep if state == `"`MyState'"'
* etc. ...
}
THE NEED
I sometimes need to run my code for several of the FY files in C:\temp. So I'd like to create a loop for that, too. For example, if I wanted to run the code for AK, CA, and WA, for the FY14 and FY15 .dta files, I'd enter "AK", "CA", and "WA" for state in StatesToRun.dta, and "FY14" and "FY15" for a variable I could call "FY" in StatesToRun.dta. I'm just not sure how to incorporate this second variable into the loop. I read you can nest foreach statements, but I'm not sure if that's the best approach.
Being rather new to Stata, this is my best guess:
* Run code only for the states and FYs I list in StatesToRun.dta.
use "C:/temp/StatesToRun.dta", clear
levelsof state, local(statelist)
levelsof FY, local(FYlist)
foreach MyState of local statelist {
foreach MyFY of local FYlist {
use "C:/temp/SalesFigures 'MyFY'.dta", clear
keep if state == `"`MyState'"'
* etc. ...
}
}
Am I on the right path?
You don't need a loop (nor a macro) to keep observations, as dictated by some "list" in another dataset. You can use merge:
clear
set more off
*----- example file with list of interest ----
sysuse auto
keep make
drop in 6/69
list
tempfile MakesToRun
save "`MakesToRun'"
*---- work with selected observations ----
clear
set more off
sysuse auto
keep make price mpg rep78
list
// keep observations that only appear in list of interest
merge 1:1 make using "`MakesToRun'", keep(matched)
list
Check help merge and the corresponding manual entry to get a good grasp of its working.
You can do this for multiple files using a loop.
Maybe there's a better way to setup the whole thing, but we don't have enough information.
Essentially, I'm storing a directed graph of entities in CouchDB, and need to be able to find edges going IN and OUT of the graph.
SETUP:
The way the data is being stored right now is as follows. Each document represents a RELATION between two entities:
doc: {
entity1: { name: '' ... },
entity2: { name: '' ... }
...
}
I have a view which does a bunch of emits, two of which emit documents keyed on their entity1 component and on their entity2 component, so something like:
function() {
emit(['entity1', doc.entity1.name]);
emit(['entity2', doc.entity2.name]);
}
Edges are directed, and go from entity1 and entity2. So if I want to find edges going out of an entity, I just query the first emit; if I want edges going into an entity, I query the second emit.
PROBLEM:
The problem here lies in the fact that I also have the need to capture edges both going INTO and OUT OF entities. Is there a way I can group or reduce these two emits into a single bi-directional set of [x] UNIQUE pairs?
Is there a better way of organizing my view to promote this action?
It might be preferable to just create a second view. But there's nothing stopping you from cramming all sorts of different data into the same view like so:
function() {
if (doc.entity1.name == doc.entity2.name) {
emit(['self-ref', doc.entity1.name], 1);
}
emit(['both' [doc.entity1.name, doc.entity2.name]], 1);
emit(['either' [doc.entity1.name, "out"]], 1);
emit(['either' [doc.entity2.name, "in"]], 1);
emit(['out', doc.entity1.name], 1);
emit(['in', doc.entity2.name], 1);
}
Then you could easily do the following:
find all the self-ref's:
startkey=["self-ref"]&endkey=["self-ref", {}].
find all of the edges (incoming or outgoing) for a particular node:
startkey=["either", [nodeName]]&endkey=["either", [nodeName, {}]]
if you don't reduce this, then you'll still be preserving "in" vs "out" in the key. If you never need to query for all nodes with incoming or outgoing edges, then you can replace the last two emits with the "either" emits.
find all of the edges from node1 -> node2:
key=["both", [node1, node2]
as well as your original queries for incoming or outgoing for a particular node.
I'd recommend benchmarking your application's typical use cases before choosing between this combined view approach or a multi-view approach.
i'm using riak to store json documents right now, and i want to sort them based on some attribute, let's say there's a key, i.e
{
"someAttribute": "whatever",
"order": 1
}
so i want to sort the documents based on the "order".
I am currently retrieving the documents in riak with the erlang interface. i can retrieve the document back as a string, but i dont' really know what to do after that. i'm thinking the map function just reduces the json document itself, and in the reduce function, i'd make a check to see whether the item i'm looking at has a higher "order" than the head of the rest of the list, and if so append to beginning, and then return a lists:reverse.
despite my ideas above i've had zero results after almost an entire day, i'm so confused with the erlang interface in riak. can someone provide insight on how to write this map/reduce function, or just how to parse the json document?
As far as I know, You do not have access to Input list in Map. You emit from Map a document as 1 element list.
Inputs (all the docs to handle as {Bucket, Key}) -> Map (handle single doc) -> Reduce (whole list emitted from Map).
Maps are executed per each doc on many nodes whereas Reduce is done once on so called coordinator node (the one where query was called).
Solution:
Define Inputs (as a list or bucket)
Retrieve Value in Map and emit whole doc or {Id, Val_to_sort_by)
Sort in Reduce (using regular list:keysort)
This is not a map reduce solution but you should check out Riak Search.
so i "solved" the problem using javascript, still can't do it using erlang.
here is my query
{"inputs":"test",
"query":[{"map":{"language":"javascript",
"source":"function(value, keyData, arg){ var data = Riak.mapValuesJson(value)[0]; var obj = {}; obj[data.order] = data; return [ obj ];}"}},
{"reduce":{"language":"javascript",
"source":"function(values, arg){ return [ values.reduce(function(acc, item){ for(var order in item){ acc[order] = item[order]; } return acc; }) ];}",
"keep":true}}
]
}
so in the map phase, all i do is create a new array, obj, with the key as the order, and the value as the data itself. so visually, the obj is like this
{"1":{"firstName":"John","order":1}
in the reduce phase, i'm just putting it in the accumulator, so basically that's the sort if you think about it, because when you're done, everything will be put in order for you. so i put 2 json documents for testing, one is above, the ohter is just firstName: Billie, order 2. and here is my result for the query above
[{"1":{"firstName":"John","order":1},"2":{"firstName":"Billie","order":2}}]
so it works! . but i still need to do this in ERLANG, any insights?