Combination (Cross-Reference) Search
Combination search lets a single query combine a container — a building or a category — with one or more entity terms scoped inside it. A search for business 101 finds unit 101 inside the Business Center; coffee shop finds shops tagged Coffee. It runs as an additive layer on top of the standard unified search, surfacing "results inside a container" alongside the normal results.
Availability
New in iOS SDK 26.7.1. Combination search is part of unified (General) search and is on by default. The feature flags are on MapUICustomParams (import MapstedMapUi); the underlying matcher CombinationSearchMatcher is public in MapstedCore for advanced use.
Enabling and disabling
Combination search is enabled by default whenever unified search is active. You can toggle either flag:
import MapstedMapUi
// Both are true by default.
MapUICustomParams.shared.unifiedSearchEnabled = true // the General (unified) search
MapUICustomParams.shared.combinationSearchEnabled = true // the combination/cross-reference layer
Android: combination search is applied automatically by the Android search subsystem; there is no separate enable/disable flag. For custom search UIs, use the matcher directly (below).
Set combinationSearchEnabled = false to keep unified search but drop the combination layer.
How a query is interpreted
The matcher tokenizes the query, decides which tokens identify a container, and leaves the rest as entity terms scoped to that container:
business 101→ containerbusiness(matches the Business Center building) + entity token101→ units named/keyed101inside that building.coffee shop→ containercoffee(matches the Coffee category) + entity tokenshop→ POIs tagged Coffee whose name or keywords containshop.
Container matching is generic — there is no maintained keyword list. Numeric tokens (like 101) are never treated as a container, and a container only engages when a query token distinctively matches one of its name words.
There is no SearchScope type
Search scoping is expressed by the SearchInSection enum (.General, .Buildings, .POI, .Categories, .Tags, .MapOverlayItems). Combination search runs in the .General (unified) scope. There is no SearchScope enum or .GENERAL constant.
Advanced: using the matcher directly
For custom search UIs you can call the pure, UI-free CombinationSearchMatcher yourself. Build a Candidate per container (its key is any type you choose — a building id, a category name), then match a query against them. Each Match gives you the container's key, a score, a coverage fraction, and the residual entityTokens to apply to your entity-scoped search.
import com.mapsted.positioning.coreObjects.CombinationSearchMatcher;
import java.util.*;
// Build candidates (key + tokenized name words), then match a query.
List<CombinationSearchMatcher.Candidate<Integer>> candidates = new ArrayList<>();
candidates.add(new CombinationSearchMatcher.Candidate<>(101, Arrays.asList("nike", "store")));
List<CombinationSearchMatcher.Match<Integer>> matches =
CombinationSearchMatcher.match("nike shoes", candidates);
for (CombinationSearchMatcher.Match<Integer> m : matches) {
Integer key = m.getKey();
double score = m.getScore();
double coverage = m.getCoverage();
}
// Low-level tokenizer, if you need it:
List<CombinationSearchMatcher.Token> tokens = CombinationSearchMatcher.tokenize("nike shoes");
import MapstedCore
// Describe the containers you want to match against.
let candidates = [
CombinationSearchMatcher.Candidate(key: 101, nameWords: ["business", "center"]),
CombinationSearchMatcher.Candidate(key: 102, nameWords: ["medical", "center"]),
]
// Match a query. Results are ordered by score, then coverage.
let matches = CombinationSearchMatcher.match("business 101", candidates)
for match in matches {
print("container \(match.key): score=\(match.score), coverage=\(match.coverage)")
print("apply these entity tokens inside it: \(match.entityTokens)") // ["101"]
}
// You can also tokenize a query yourself.
let tokens = CombinationSearchMatcher.tokenize("business center") // [business, center]
Candidate is generic over its key type (Candidate<K>), so use Int keys for buildings, String keys for categories, or whatever identifies your containers.
Tips & Considerations
- Numeric tokens never match a container.
101is always an entity term, never a building/category — by design. - A container needs a distinctive match. A query engages a container only when at least one token matches a non-generic word of its name, so shared words like "Center" across many tenants do not cause false matches.
matchreturns containers ordered byscorethencoverage. Apply theentityTokensof each match to your entity search to produce the scoped results.- The high-level combination display is part of unified search. Toggle it with
MapUICustomParams.shared.combinationSearchEnabled; useCombinationSearchMatcherdirectly only when you build your own search UI.