bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
241 lines
7.1 KiB
Plaintext
241 lines
7.1 KiB
Plaintext
// QUIXZOOM Neo4j Schema
|
|
//
|
|
// Ansvarsområden:
|
|
// - Objektrelationer
|
|
// - Evidensgraf
|
|
// - Knowledge Graph
|
|
// - Relationer mellan objekt
|
|
// - Härledningar ("den här lyktstolpen tillhör denna gata")
|
|
|
|
// ============================================================
|
|
// NODER
|
|
// ============================================================
|
|
|
|
// Urban Objects
|
|
CREATE CONSTRAINT object_id IF NOT EXISTS
|
|
FOR (o:Object) REQUIRE o.object_id IS UNIQUE;
|
|
|
|
CREATE INDEX object_type IF NOT EXISTS
|
|
FOR (o:Object) ON (o.type);
|
|
|
|
CREATE INDEX object_location IF NOT EXISTS
|
|
FOR (o:Object) ON (o.location);
|
|
|
|
// Observations
|
|
CREATE CONSTRAINT observation_id IF NOT EXISTS
|
|
FOR (obs:Observation) REQUIRE obs.observation_id IS UNIQUE;
|
|
|
|
// Evidence
|
|
CREATE CONSTRAINT evidence_id IF NOT EXISTS
|
|
FOR (e:Evidence) REQUIRE e.evidence_id IS UNIQUE;
|
|
|
|
// Areas
|
|
CREATE CONSTRAINT area_id IF NOT EXISTS
|
|
FOR (a:Area) REQUIRE a.area_id IS UNIQUE;
|
|
|
|
// Zoomers
|
|
CREATE CONSTRAINT zoomer_id IF NOT EXISTS
|
|
FOR (z:Zoomer) REQUIRE z.zoomer_id IS UNIQUE;
|
|
|
|
// Missions
|
|
CREATE CONSTRAINT mission_id IF NOT EXISTS
|
|
FOR (m:Mission) REQUIRE m.mission_id IS UNIQUE;
|
|
|
|
// ============================================================
|
|
// RELATIONER
|
|
// ============================================================
|
|
|
|
// Object -> Observation (ett objekt observeras många gånger)
|
|
// (:Object)-[:OBSERVED_IN]->(:Observation)
|
|
|
|
// Object -> Evidence (ett objekt har många bevis)
|
|
// (:Object)-[:SUPPORTED_BY]->(:Evidence)
|
|
|
|
// Evidence -> Observation (bevis kommer från observation)
|
|
// (:Evidence)-[:DERIVED_FROM]->(:Observation)
|
|
|
|
// Object -> Object (relationer mellan objekt)
|
|
// (:Object)-[:NEAR {distance: 5}]->(:Object)
|
|
// (:Object)-[:CONNECTED_TO]->(:Object)
|
|
// (:Object)-[:PART_OF]->(:Object)
|
|
// (:Object)-[:SUPPORTS]->(:Object)
|
|
// (:Object)-[:OPPOSITE_TO]->(:Object)
|
|
|
|
// Object -> Area (objekt tillhör område)
|
|
// (:Object)-[:LOCATED_IN]->(:Area)
|
|
|
|
// Observation -> Zoomer (vem som observerade)
|
|
// (:Observation)-[:OBSERVED_BY]->(:Zoomer)
|
|
|
|
// Mission -> Object (uppdrag gäller objekt)
|
|
// (:Mission)-[:TARGETS]->(:Object)
|
|
|
|
// Mission -> Area (uppdrag i område)
|
|
// (:Mission)-[:IN_AREA]->(:Area)
|
|
|
|
// Mission -> Zoomer (uppdrag tilldelat zoomer)
|
|
// (:Mission)-[:ASSIGNED_TO]->(:Zoomer)
|
|
|
|
// Object -> Object (temporal — ersätter)
|
|
// (:Object)-[:REPLACED_BY {date: '2026-11-02'}]->(:Object)
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Skapa objekt med relationer
|
|
// ============================================================
|
|
|
|
// Skapa gatlykta
|
|
CREATE (lamp:Object {
|
|
object_id: 'street_lamp_3e6a09cfabc7',
|
|
type: 'street_lamp',
|
|
subtype: 'led',
|
|
location: point({latitude: 13.725, longitude: 100.555}),
|
|
attributes: {
|
|
material: 'steel',
|
|
height: 7.8,
|
|
paint: 'grey',
|
|
rust: false,
|
|
lean: 0,
|
|
light: 'working'
|
|
},
|
|
verification_status: 'verified',
|
|
confidence: 0.94,
|
|
first_seen: datetime('2026-06-01T00:00:00Z'),
|
|
last_seen: datetime('2026-06-28T08:15:30Z')
|
|
});
|
|
|
|
// Skapa observation
|
|
CREATE (obs:Observation {
|
|
observation_id: 'obs_1782638086138_ab6ndwzwo',
|
|
source_type: 'quixzoom',
|
|
source_id: 'zoomer_001',
|
|
timestamp: datetime('2026-06-28T08:15:30Z'),
|
|
quality: {
|
|
resolution: 1080,
|
|
sharpness: 0.9
|
|
}
|
|
});
|
|
|
|
// Skapa evidens
|
|
CREATE (ev:Evidence {
|
|
evidence_id: 'ev_1782638086138_h3fstkqnd',
|
|
proof_type: 'video',
|
|
proof_url: 'https://r2.landvex.com/videos/bangkok_001.mp4#frame=342',
|
|
reliability: 0.85,
|
|
timestamp: datetime('2026-06-28T08:15:30Z')
|
|
});
|
|
|
|
// Skapa relationer
|
|
MATCH (lamp:Object {object_id: 'street_lamp_3e6a09cfabc7'})
|
|
MATCH (obs:Observation {observation_id: 'obs_1782638086138_ab6ndwzwo'})
|
|
MATCH (ev:Evidence {evidence_id: 'ev_1782638086138_h3fstkqnd'})
|
|
CREATE (lamp)-[:OBSERVED_IN]->(obs)
|
|
CREATE (lamp)-[:SUPPORTED_BY]->(ev)
|
|
CREATE (ev)-[:DERIVED_FROM]->(obs);
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Spatiala relationer
|
|
// ============================================================
|
|
|
|
// Hitta objekt nära en plats
|
|
MATCH (o:Object)
|
|
WHERE point.distance(o.location, point({latitude: 13.725, longitude: 100.555})) < 50
|
|
RETURN o.object_id, o.type, o.location;
|
|
|
|
// Hitta närliggande objekt
|
|
MATCH (o1:Object)-[:NEAR]->(o2:Object)
|
|
WHERE o1.object_id = 'street_lamp_3e6a09cfabc7'
|
|
RETURN o2.object_id, o2.type;
|
|
|
|
// Hitta alla objekt av en typ i ett område
|
|
MATCH (o:Object)-[:LOCATED_IN]->(a:Area)
|
|
WHERE a.name = 'Sukhumvit' AND o.type = 'street_lamp'
|
|
RETURN o.object_id, o.location, o.attributes;
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Härledningar
|
|
// ============================================================
|
|
|
|
// "Den här lyktstolpen tillhör denna gata"
|
|
MATCH (lamp:Object {type: 'street_lamp'})
|
|
MATCH (road:Object {type: 'road'})
|
|
WHERE point.distance(lamp.location, road.location) < 10
|
|
CREATE (lamp)-[:PART_OF {confidence: 0.9}]->(road);
|
|
|
|
// Hitta alla lyktstolpar på en gata
|
|
MATCH (road:Object {object_id: 'sukhumvit_road'})
|
|
<-[:PART_OF]-(lamp:Object)
|
|
RETURN lamp.object_id, lamp.attributes;
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Temporal
|
|
// ============================================================
|
|
|
|
// Gatlykta ersatt
|
|
MATCH (old:Object {object_id: 'street_lamp_3e6a09cfabc7'})
|
|
CREATE (new:Object {
|
|
object_id: 'street_lamp_new_001',
|
|
type: 'street_lamp',
|
|
location: point({latitude: 13.725, longitude: 100.555}),
|
|
attributes: {
|
|
material: 'aluminum',
|
|
height: 8.0,
|
|
paint: 'black',
|
|
rust: false,
|
|
lean: 0,
|
|
light: 'working'
|
|
},
|
|
verification_status: 'verified',
|
|
confidence: 0.98,
|
|
first_seen: datetime('2026-11-02T00:00:00Z')
|
|
})
|
|
CREATE (old)-[:REPLACED_BY {date: datetime('2026-11-02T00:00:00Z')}]->(new);
|
|
|
|
// Hitta ersättningskedja
|
|
MATCH (old:Object)-[:REPLACED_BY*]->(new:Object)
|
|
WHERE old.object_id = 'street_lamp_3e6a09cfabc7'
|
|
RETURN old, new;
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Evidensgraf
|
|
// ============================================================
|
|
|
|
// Hitta alla bevis för ett objekt
|
|
MATCH (o:Object {object_id: 'street_lamp_3e6a09cfabc7'})
|
|
-[:SUPPORTED_BY]->(e:Evidence)
|
|
RETURN e.evidence_id, e.proof_type, e.reliability, e.source_type;
|
|
|
|
// Hitta objekt med flest bevis
|
|
MATCH (o:Object)-[:SUPPORTED_BY]->(e:Evidence)
|
|
WITH o, count(e) as evidence_count
|
|
ORDER BY evidence_count DESC
|
|
LIMIT 10
|
|
RETURN o.object_id, o.type, evidence_count;
|
|
|
|
// ============================================================
|
|
// EXEMPEL: Knowledge Graph-frågor
|
|
// ============================================================
|
|
|
|
// Hitta objekt som behöver verifiering
|
|
MATCH (o:Object)
|
|
WHERE o.verification_status = 'unverified'
|
|
RETURN o.object_id, o.type, o.location, o.confidence;
|
|
|
|
// Hitta objekt med låg konfidens
|
|
MATCH (o:Object)
|
|
WHERE o.confidence < 0.5
|
|
RETURN o.object_id, o.type, o.confidence;
|
|
|
|
// Hitta "ensamma" objekt (få relationer)
|
|
MATCH (o:Object)
|
|
OPTIONAL MATCH (o)-[r]-()
|
|
WITH o, count(r) as relation_count
|
|
WHERE relation_count < 2
|
|
RETURN o.object_id, o.type, relation_count;
|
|
|
|
// Hitta objekt med motsägande evidens
|
|
MATCH (o:Object)-[:SUPPORTED_BY]->(e1:Evidence)
|
|
MATCH (o)-[:SUPPORTED_BY]->(e2:Evidence)
|
|
WHERE e1.reliability > 0.8 AND e2.reliability > 0.8
|
|
AND e1.proof_type <> e2.proof_type
|
|
RETURN o.object_id, count(e1) as evidence_count;
|