findTriples method
- RdfSubject? subject,
- Iterable<
RdfSubject> ? subjectIn, - RdfPredicate? predicate,
- Iterable<
RdfPredicate> ? predicateIn, - RdfObject? object,
- Iterable<
RdfObject> ? objectIn,
Find all triples matching the given pattern
This method returns triples that match all the specified pattern components. Unlike withoutMatching, this method uses AND logic - all specified components must match. If a pattern component is null, it acts as a wildcard.
Set-based Queries: The *In parameters allow efficient querying for
triples that match any value in a set. When multiple values are provided
via these parameters, the method returns triples matching ANY of those values
(OR logic within the set), while different parameter types still use AND logic.
Performance: When subjectIn is used with indexing enabled, this method
leverages the internal index structure for optimal performance, especially
beneficial when querying for multiple subjects.
Parameters:
subjectOptional subject to match (exact match)subjectInOptional set of subjects - matches triples with ANY of these subjectspredicateOptional predicate to match (exact match)predicateInOptional set of predicates - matches triples with ANY of these predicatesobjectOptional object to match (exact match)objectInOptional set of objects - matches triples with ANY of these objects
Note: If both subject and subjectIn are provided, they are combined.
The same applies to predicate/predicateIn and object/objectIn pairs.
Empty sets in *In parameters will match nothing.
Returns: List of matching triples as an unmodifiable collection. The list may be empty if no matching triples exist.
Example:
// Find all statements about John
final johnsTriples = graph.findTriples(subject: john);
// Find all name statements
final nameTriples = graph.findTriples(predicate: name);
// Find John's name specifically
final johnsName = graph.findTriples(subject: john, predicate: name);
// Find statements about John OR Jane (set-based query)
final multipleSubjects = graph.findTriples(subjectIn: [john, jane]);
// Find name OR email properties (set-based query)
final contactInfo = graph.findTriples(predicateIn: [name, email]);
// Combine set-based and exact match filters
final johnOrJaneName = graph.findTriples(
subjectIn: [john, jane],
predicate: name,
);
// Complex query with multiple sets
final results = graph.findTriples(
subjectIn: [john, jane, bob],
predicateIn: [name, email],
objectIn: [targetValue1, targetValue2],
);
Implementation
List<Triple> findTriples({
RdfSubject? subject,
Iterable<RdfSubject>? subjectIn,
RdfPredicate? predicate,
Iterable<RdfPredicate>? predicateIn,
RdfObject? object,
Iterable<RdfObject>? objectIn,
}) {
final subjectSet = (subject != null || subjectIn != null)
? {if (subject != null) subject, ...?subjectIn}
: null;
final predicateSet = (predicate != null || predicateIn != null)
? {if (predicate != null) predicate, ...?predicateIn}
: null;
final objectSet = (object != null || objectIn != null)
? {if (object != null) object, ...?objectIn}
: null;
if (subjectSet != null && _effectiveIndex != null) {
final index = _effectiveIndex!;
// If subjectSet is empty, the for loop simply won't run, correctly returning [].
final List<Triple> results = [];
for (final s in subjectSet) {
final subjectMap = index[s];
if (subjectMap == null) continue;
final Iterable<Triple> candidates;
if (predicateSet != null) {
// If predicateSet is empty, this correctly produces no candidates.
candidates = predicateSet
.map((p) => subjectMap[p])
.nonNulls
.expand((list) => list);
} else {
candidates = subjectMap.values.expand((list) => list);
}
if (objectSet != null) {
// If objectSet is empty, .where() will correctly filter everything out.
results.addAll(
candidates.where((triple) => objectSet.contains(triple.object)));
} else {
results.addAll(candidates);
}
}
return List.unmodifiable(results);
}
return List.unmodifiable(
_triples.where(
(triple) => _matches(triple, subjectSet, predicateSet, objectSet)),
);
}