use of won.protocol.util.NeedModelWrapper in project webofneeds by researchstudio-sat.
the class GoalInstantiationTest method exampleTaxi_validity.
@Test
public void exampleTaxi_validity() throws IOException {
Dataset taxiOffer = loadDataset(baseFolder + "ex6_taxioffer.trig");
Dataset taxiDemand = loadDataset(baseFolder + "ex6_taxi.trig");
Dataset taxiDemandNoLoc = loadDataset(baseFolder + "ex6_taxi_noloc.trig");
Dataset taxiDemandTwoLoc = loadDataset(baseFolder + "ex6_taxi_twoloc.trig");
GoalInstantiationProducer goalInstantiation = new GoalInstantiationProducer(taxiOffer, taxiDemand, null, "http://example.org/", "http://example.org/blended/");
Collection<GoalInstantiationResult> results = goalInstantiation.createGoalInstantiationResultsForNeed1();
for (GoalInstantiationResult res : results) {
System.out.println("Result::::::::::::::::::::::::::::::" + res.isConform());
System.out.println(res.toString());
if (res.isConform()) {
Coordinate departureAddress = getAddress(loadSparqlQuery("/won/utils/goals/extraction/address/fromLocationQuery.rq"), res.getInstanceModel());
Coordinate destinationAddress = getAddress(loadSparqlQuery("/won/utils/goals/extraction/address/toLocationQuery.rq"), res.getInstanceModel());
Assert.assertEquals(departureAddress, new Coordinate(10.0f, 11.0f));
Assert.assertEquals(destinationAddress, new Coordinate(12.0f, 13.0f));
}
}
NeedModelWrapper needWrapper1 = new NeedModelWrapper(taxiOffer);
Resource goal = needWrapper1.getGoals().iterator().next();
GoalInstantiationResult result = goalInstantiation.findInstantiationForGoal(goal);
Assert.assertTrue(result.isConform());
GoalInstantiationResult recheckResultModel = GoalInstantiationProducer.findInstantiationForGoalInDataset(taxiOffer, goal, result.getInstanceModel());
Assert.assertTrue(recheckResultModel.isConform());
goalInstantiation = new GoalInstantiationProducer(taxiOffer, taxiDemandNoLoc, null, "http://example.org/", "http://example.org/blended/");
results = goalInstantiation.createGoalInstantiationResultsForNeed1();
for (GoalInstantiationResult res : results) {
Assert.assertFalse(res.isConform());
}
goalInstantiation = new GoalInstantiationProducer(taxiOffer, taxiDemandTwoLoc, null, "http://example.org/", "http://example.org/blended/");
results = goalInstantiation.createGoalInstantiationResultsForNeed1();
for (GoalInstantiationResult res : results) {
Assert.assertFalse(res.isConform());
}
}
use of won.protocol.util.NeedModelWrapper in project webofneeds by researchstudio-sat.
the class SolrMatcherActor method processActiveNeedEvent.
protected void processActiveNeedEvent(NeedEvent needEvent) throws IOException, SolrServerException, JsonLdError {
log.info("Start processing active need event {}", needEvent);
// check if the need has doNotMatch flag, then do not use it for querying or indexing
Dataset dataset = needEvent.deserializeNeedDataset();
NeedModelWrapper needModelWrapper = new NeedModelWrapper(dataset);
if (needModelWrapper.hasFlag(WON.NO_HINT_FOR_ME) && needModelWrapper.hasFlag(WON.NO_HINT_FOR_COUNTERPART)) {
log.info("Discarding received need due to flags won:NoHintForMe and won:NoHintForCounterpart: {}", needEvent);
return;
}
// check if need is usedForTesting only
boolean usedForTesting = needModelWrapper.hasFlag(WON.USED_FOR_TESTING);
SolrMatcherQueryExecutor queryExecutor = (usedForTesting ? testQueryExecuter : defaultQueryExecuter);
// create another query depending if the current need is "WhatsAround" or a default need
String queryString = null;
if (needModelWrapper.hasFlag(WON.WHATS_AROUND)) {
// WhatsAround doesnt match on terms only other needs in close location are boosted
WhatsAroundQueryFactory qf = new WhatsAroundQueryFactory(dataset);
queryString = qf.createQuery();
} else {
// default query matches content terms (of fields title, description and tags) with different weights
// and gives an additional multiplicative boost for geographically closer needs
DefaultNeedQueryFactory qf = new DefaultNeedQueryFactory(dataset);
queryString = qf.createQuery();
}
// add filters to the query: default filters are
// - need status active
// - creation date overlap 1 month
// - OR-filtering for matching contexts if any were specified
// now create three slightly different queries for different lists of needs:
// 1) needs without NoHintForCounterpart => hints for current need
// 2) needs without NoHintForSelf, excluding WhatsAround needs => hints for needs in index that are not WhatsAround
// 3) needs without NoHintForSelf that are only WhatsAround needs => hints for needs in index that are WhatsAround
// to achieve this use a different filters for these queries
// case 1) needs without NoHintForCounterpart => hints for current need
List<String> filterQueries = new LinkedList<>();
filterQueries.add(new NeedStateQueryFactory(dataset).createQuery());
filterQueries.add(new CreationDateQueryFactory(dataset, 1, ChronoUnit.MONTHS).createQuery());
filterQueries.add(new BooleanQueryFactory(BooleanQueryFactory.BooleanOperator.NOT, new HasFlagQueryFactory(HasFlagQueryFactory.FLAGS.NO_HINT_FOR_COUNTERPART)).createQuery());
if (needModelWrapper.getMatchingContexts() != null && needModelWrapper.getMatchingContexts().size() > 0) {
filterQueries.add(new MatchingContextQueryFactory(needModelWrapper.getMatchingContexts()).createQuery());
}
if (!needModelWrapper.hasFlag(WON.NO_HINT_FOR_ME)) {
// execute the query
log.info("query Solr endpoint {} for need {} and need list 1 (without NoHintForCounterpart)", config.getSolrEndpointUri(usedForTesting), needEvent.getUri());
SolrDocumentList docs = queryExecutor.executeNeedQuery(queryString, null, filterQueries.toArray(new String[filterQueries.size()]));
if (docs != null) {
// generate hints for current need (only generate hints for current need, suppress hints for matched needs,
// perform knee detection depending on current need is WhatsAround or not)
BulkHintEvent events = null;
if (needModelWrapper.hasFlag(WON.WHATS_AROUND)) {
events = hintBuilder.generateHintsFromSearchResult(docs, needEvent, needModelWrapper, false, true, false);
} else {
events = hintBuilder.generateHintsFromSearchResult(docs, needEvent, needModelWrapper, false, true, true);
}
log.info("Create {} hints for need {} and need list 1 (without NoHintForCounterpart)", events.getHintEvents().size(), needEvent);
// publish hints to current need
if (events.getHintEvents().size() != 0) {
getSender().tell(events, getSelf());
}
} else {
log.warning("No results found for need list 1 (without NoHintForCounterpart) query of need ", needEvent);
}
}
// case 2) needs without NoHintForSelf, excluding WhatsAround needs => hints for needs in index that are not WhatsAround
filterQueries = new LinkedList<>();
filterQueries.add(new NeedStateQueryFactory(dataset).createQuery());
filterQueries.add(new CreationDateQueryFactory(dataset, 1, ChronoUnit.MONTHS).createQuery());
filterQueries.add(new BooleanQueryFactory(BooleanQueryFactory.BooleanOperator.NOT, new HasFlagQueryFactory(HasFlagQueryFactory.FLAGS.NO_HINT_FOR_ME)).createQuery());
filterQueries.add(new BooleanQueryFactory(BooleanQueryFactory.BooleanOperator.NOT, new HasFlagQueryFactory(HasFlagQueryFactory.FLAGS.WHATS_AROUND)).createQuery());
if (needModelWrapper.getMatchingContexts() != null && needModelWrapper.getMatchingContexts().size() > 0) {
filterQueries.add(new MatchingContextQueryFactory(needModelWrapper.getMatchingContexts()).createQuery());
}
if (!needModelWrapper.hasFlag(WON.NO_HINT_FOR_COUNTERPART)) {
// execute the query
log.info("query Solr endpoint {} for need {} and need list 2 (without NoHintForSelf, excluding WhatsAround needs)", config.getSolrEndpointUri(usedForTesting), needEvent.getUri());
SolrDocumentList docs = queryExecutor.executeNeedQuery(queryString, null, filterQueries.toArray(new String[filterQueries.size()]));
if (docs != null) {
// generate hints for matched needs (suppress hints for current need, only generate hints for matched needs, perform knee detection)
BulkHintEvent events = hintBuilder.generateHintsFromSearchResult(docs, needEvent, needModelWrapper, true, false, true);
log.info("Create {} hints for need {} and need list 2 (without NoHintForSelf, excluding WhatsAround needs)", events.getHintEvents().size(), needEvent);
// publish hints to current need
if (events.getHintEvents().size() != 0) {
getSender().tell(events, getSelf());
}
} else {
log.warning("No results found for need list 2 (without NoHintForSelf, excluding WhatsAround needs) query of need ", needEvent);
}
}
// case 3) needs without NoHintForSelf that are only WhatsAround needs => hints for needs in index that are WhatsAround
filterQueries = new LinkedList<>();
filterQueries.add(new NeedStateQueryFactory(dataset).createQuery());
filterQueries.add(new CreationDateQueryFactory(dataset, 1, ChronoUnit.MONTHS).createQuery());
filterQueries.add(new BooleanQueryFactory(BooleanQueryFactory.BooleanOperator.NOT, new HasFlagQueryFactory(HasFlagQueryFactory.FLAGS.NO_HINT_FOR_ME)).createQuery());
filterQueries.add(new HasFlagQueryFactory(HasFlagQueryFactory.FLAGS.WHATS_AROUND).createQuery());
if (needModelWrapper.getMatchingContexts() != null && needModelWrapper.getMatchingContexts().size() > 0) {
filterQueries.add(new MatchingContextQueryFactory(needModelWrapper.getMatchingContexts()).createQuery());
}
if (!needModelWrapper.hasFlag(WON.NO_HINT_FOR_COUNTERPART)) {
// execute the query
log.info("query Solr endpoint {} for need {} and need list 3 (without NoHintForSelf that are only WhatsAround needs)", config.getSolrEndpointUri(usedForTesting), needEvent.getUri());
SolrDocumentList docs = queryExecutor.executeNeedQuery(queryString, null, filterQueries.toArray(new String[filterQueries.size()]));
if (docs != null) {
// generate hints for matched needs (suppress hints for current need, only generate hints for matched needs, do not perform knee detection)
BulkHintEvent events = hintBuilder.generateHintsFromSearchResult(docs, needEvent, needModelWrapper, true, false, false);
log.info("Create {} hints for need {} and need list 3 (without NoHintForSelf that are only WhatsAround needs)", events.getHintEvents().size(), needEvent);
// publish hints to current need
if (events.getHintEvents().size() != 0) {
getSender().tell(events, getSelf());
}
} else {
log.warning("No results found for need list 3 (without NoHintForSelf that are only WhatsAround needs) query of need ", needEvent);
}
}
// index need
log.info("Add need event content {} to solr index", needEvent);
needIndexer.index(dataset);
}
use of won.protocol.util.NeedModelWrapper in project webofneeds by researchstudio-sat.
the class NeedIndexer method index.
public void index(Dataset dataset) throws IOException, JsonLdError {
// serialize the need Dataset to jsonld
Query query = QueryFactory.create(NEED_INDEX_QUERY);
QueryExecution qexec = QueryExecutionFactory.create(query, dataset);
Model needModel = qexec.execConstruct();
// normalize the need model for solr indexing
NeedModelWrapper needModelWrapper = new NeedModelWrapper(needModel, null);
String needUri = needModelWrapper.getNeedUri();
needModel = needModelWrapper.normalizeNeedModel();
// check if test index should be used for need
boolean usedForTesting = needModelWrapper.hasFlag(WON.USED_FOR_TESTING);
indexNeedModel(needModel, needUri, usedForTesting);
}
use of won.protocol.util.NeedModelWrapper in project webofneeds by researchstudio-sat.
the class SolrNeedIndexer method main.
public static void main(String[] args) throws IOException, InterruptedException, JsonLdError {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SolrTestAppConfiguration.class);
NeedIndexer indexer = ctx.getBean(NeedIndexer.class);
// set the options of the need producer (e.g. if it should exhaust) in the SolrNeedIndexerAppConfiguration file
NeedProducer needProducer = ctx.getBean(RoundRobinCompositeNeedProducer.class);
Model needModel = new NeedModelWrapper(needProducer.create()).copyNeedModel(NeedGraphType.NEED);
int needs = 0;
while (!needProducer.isExhausted()) {
// indexer.indexNeedModel(needModel, UUID.randomUUID().toString(), true);
Dataset ds = DatasetFactory.createTxnMem();
ds.addNamedModel("https://node.matchat.org/won/resource/need/test#need", needModel);
NeedModelWrapper needModelWrapper = new NeedModelWrapper(needModel, null);
needModel = needModelWrapper.normalizeNeedModel();
indexer.indexNeedModel(needModel, SolrMatcherEvaluation.createNeedId(ds), true);
needs++;
if (needs % 100 == 0) {
System.out.println("Indexed " + needs + " needs.");
}
needModel = new NeedModelWrapper(needProducer.create()).copyNeedModel(NeedGraphType.NEED);
}
System.out.println("Indexed " + needs + " needs.");
System.exit(0);
}
use of won.protocol.util.NeedModelWrapper in project webofneeds by researchstudio-sat.
the class GoalInstantiationProducer method findInstantiationForGoals.
/**
* Create a goal instantiation result from the attempt to instantiate two goals of two needs using all
* the need data, the conversation data and the data and shapes of the two goals.
* If a model can be found that conforms to the shacl shapes of both needs this model is chosen to be returned
* in the GoalInstantiationResult. If no conforming model can be found, the model with the least
* shacl validation results (validation errors) is used.
*
* @param goal1 resource referencing goal from need1
* @param goal2 resource referencing goal from need2
* @return a goal instantiation result whose input model can either conform to its shacl shapes or not
*/
private GoalInstantiationResult findInstantiationForGoals(Resource goal1, Resource goal2) {
NeedModelWrapper needWrapper1 = new NeedModelWrapper(need1);
Model shapesModel1 = needWrapper1.getShapesGraph(goal1);
Model dataModel1 = needWrapper1.getDataGraph(goal1);
NeedModelWrapper needWrapper2 = new NeedModelWrapper(need2);
Model shapesModel2 = needWrapper2.getShapesGraph(goal2);
Model dataModel2 = needWrapper2.getDataGraph(goal2);
if (shapesModel1 == null || shapesModel2 == null) {
throw new IllegalArgumentException("shapes model for goal not found");
}
// create the combined model with need content, conversation data and the data of the two goals
Model combinedModelWithGoalData = ModelFactory.createDefaultModel();
combinedModelWithGoalData.add(combinedModelWithoutGoals);
if (dataModel1 != null) {
combinedModelWithGoalData.add(dataModel1);
}
if (dataModel2 != null) {
combinedModelWithGoalData.add(dataModel2);
}
// validate the two goal shapes against the combined data model
// and extract specific data for each goal using the shacl results
Model extractedModel1 = GoalUtils.extractGoalData(combinedModelWithGoalData, shapesModel1);
Model extractedModel2 = GoalUtils.extractGoalData(combinedModelWithGoalData, shapesModel2);
Model combinedShapesModel = ModelFactory.createDefaultModel();
combinedShapesModel.add(shapesModel1);
combinedShapesModel.add(shapesModel2);
int minValidationResults = Integer.MAX_VALUE;
GoalInstantiationResult bestGoalInstantiationResult = null;
// blend the two extracted graphs
GraphBlendingIterator blendingIterator = new GraphBlendingIterator(extractedModel1, extractedModel2, variableUriPrefix, blendingUriPrefix);
while (blendingIterator.hasNext()) {
Model blendedModel = blendingIterator.next();
// check if the blended model conforms to the combined shacl shapes of both needs
Resource report = ValidationUtil.validateModel(blendedModel, combinedShapesModel, false);
ShaclReportWrapper shaclReportWrapper = new ShaclReportWrapper(report);
if (shaclReportWrapper.isConform()) {
// if we found a blended model that is conform to the shacl shapes lets try to condense it
// as far as possible to get the minimum model that is still conform to the shapes
Function<Model, Boolean> modelTestingFunction = param -> GoalUtils.validateModelShaclConformity(param, combinedShapesModel);
Model condensedModel = RdfUtils.condenseModelByIterativeTesting(blendedModel, modelTestingFunction);
bestGoalInstantiationResult = new GoalInstantiationResult(condensedModel, combinedShapesModel);
} else {
// if the model is not conform save it if it has the least validation results found so far
if (shaclReportWrapper.getValidationResults().size() < minValidationResults) {
minValidationResults = shaclReportWrapper.getValidationResults().size();
bestGoalInstantiationResult = new GoalInstantiationResult(blendedModel, combinedShapesModel);
}
}
}
return bestGoalInstantiationResult;
}
Aggregations