Exploring op.fromLexicons()
Turn indexed lexicon values into join-friendly row plans
op.fromLexicons() sources rows directly from range, URI, and collection lexicons. That makes it a strong fit when you need indexed values in a row shape ready for projection, filtering, or joining in a larger plan.
If you need a refresher on lexicon fundamentals, see Understanding Lexicons. The key difference: use this when you want fragment-linked lexicon rows rather than just a distinct value list.
Llamaverse Context for This API Call
| Context Item | What this article uses |
|---|---|
| Data set | llamaverse v2.0+ sample data |
| Primary source documents | wild llama JSON documents |
| Lexicon references shown | JSON property and path range references (for example breed and root-level identifiers) |
| Views used | None (this call reads lexicons directly) |
| Field usage | None in these examples |
| Index context | required range/path indexes must exist before op.fromLexicons() can return rows |
If the plan returns no rows, validate index definitions first. op.fromLexicons() cannot infer values for indexes that are missing or misconfigured.
Source Docs and Configuration Used
| Item | Value used in this article |
|---|---|
| MarkLogic API docs | op:from-lexicons, op.fromLexicons, cts:values |
| Llamaverse source collection | wild-llamas |
| Llamaverse source URI pattern | /cleverllamas/llamaverse/raw/wild-llamas/llamas/{uuid}.json |
| Required database config | Path range index on /heightCm (type=int) and range reference for breed used in the examples |
Parameters
| Name | Datatype | Required | Notes |
|---|---|---|---|
indexdef | Object | Yes | An object defining the lexicon columns to retrieve, where each key is a column name and each value is a cts.reference for the index. |
qualifier | String | No | Optional runtime alias for projected columns when plans need clearer naming. |
systemCols | String | No | Optional system columns (for example fragment ID) for downstream joins and diagnostics. |
Setup
The examples rely on two additional indexes that are included in the llamaverse.
Path Range Index
A path range index on top-level id matches non-enveloped documents including wild llamas.
JSON Property Range Index
A JSON property range index on breed. In Admin UI terminology this is configured via element-style controls even for JSON nodes. Treat UI wording as implementation detail and always verify the actual index reference used in code.
Comparison to cts.values()
Start with a direct comparison to cts:values(). cts:values() returns distinct values only, regardless of how many fragments contain each value. You can filter that set, but you do not get fragment-linked rows directly.
op.fromLexicons() returns a row plan with fragment linkage exposed. The practical consequence is one row per fragment, not one row per unique value.
{
"name": "Aaron",
"breed": "Huacaya",
"placeOfBirth": "Cusco, Peru",
"secretPowerId": "d8839ba6-2b77-4bcc-9927-b86cdfecb9fb"
}
xquery version "1.0-ml";
cts:values(cts:element-reference(xs:QName("breed")))
'use strict';
const results = cts.values(cts.elementReference(xs.QName('breed'))).toArray();
({
sample: 'optic/op-from-lexicons/assets/cts-values-comparison.sjs',
kind: Array.isArray(results) ? (results.every((item) => typeof item === 'object' && 'subject' in item && 'predicate' in item && 'object' in item) ? 'triples' : 'rows') : ((results !== null && typeof results === 'object') ? 'object' : 'scalar'),
count: Array.isArray(results) ? results.length : 0,
data: results
});
Huacaya
Hybrid
Suri
xquery version "1.0-ml";
import module namespace op = "http://marklogic.com/optic" at "/MarkLogic/optic.xqy";
op:from-lexicons(
map:entry("breed", cts:json-property-reference("breed"))
)
=> op:result()
'use strict';
const op = require('/MarkLogic/optic');
const results = op.fromLexicons({ breed: cts.jsonPropertyReference('breed') })
.result();
({
sample: 'optic/op-from-lexicons/assets/from-lexicons-breed.sjs',
kind: Array.isArray(results) ? (results.every((item) => typeof item === 'object' && 'subject' in item && 'predicate' in item && 'object' in item) ? 'triples' : 'rows') : ((results !== null && typeof results === 'object') ? 'object' : 'scalar'),
count: Array.isArray(results) ? results.length : 0,
data: results
});
[
{
"breed": "Huacaya"
},
... hundreds of other rows with Huacaya
{
"breed": "Huacaya"
},
{
"breed": "Hybrid"
},
... hundreds of other rows with Hybrid
{
"breed": "Suri"
},
{
... hundreds of other rows with Suri
}
.... thousands of rows in total
]
Example
xquery version "1.0-ml";
import module namespace op = "http://marklogic.com/optic" at "/MarkLogic/optic.xqy";
op:from-lexicons(
map:entry("breed", cts:element-reference(xs:QName("breed")))
=> map:with("heightCm", cts:path-reference("/heightCm", ("type=int"))),
(),
op:fragment-id-col("fragmentId")
)
=> op:where(op:eq(op:col("breed"), "Suri"))
=> op:select(("fragmentId", "breed", "heightCm"))
=> op:limit(3)
=> op:result()
'use strict';
const op = require('/MarkLogic/optic');
const plan = op.fromLexicons({
breed: cts.elementReference(xs.QName('breed')),
heightCm: cts.pathReference('/heightCm', ['type=int'])
}, null, op.fragmentIdCol('fragmentId'))
.where(op.eq(op.col('breed'), 'Suri'))
.select(['fragmentId', 'breed', 'heightCm'])
.limit(3);
const results = plan.result();
({
sample: 'optic/op-from-lexicons/assets/from-lexicons-example.sjs',
kind: Array.isArray(results) ? (results.every((item) => typeof item === 'object' && 'subject' in item && 'predicate' in item && 'object' in item) ? 'triples' : 'rows') : ((results !== null && typeof results === 'object') ? 'object' : 'scalar'),
count: Array.isArray(results) ? results.length : 0,
data: results
});
This plan retrieves llama IDs, names, and their fields from range indexes.
When to Choose op.fromLexicons()
Use op.fromLexicons() when fragment-linked index rows are the right starting point for joins, audits, or high-volume reporting.
Choose cts:values() for distinct-value summaries. Choose op.fromLexicons() when you need value plus fragment context in the same plan.
- Understanding Lexicons — Build the index foundation that
op.fromLexicons()depends on. - Optic Data Source Starter Pack — Compare lexicon-sourced rows against other Optic source shapes.
- Optic Joins Starter Pack — Join lexicon rows to view rows for richer analysis.
Need Some Help?
Looking for more information on this subject or any other topic related to MarkLogic? Contact Us (info@cleverllamas.com) to find out how we can assist you with consulting or training!
- Llamaverse Context for This API Call
- Source Docs and Configuration Used
- Parameters
- Setup
- Path Range Index
- JSON Property Range Index
- Comparison to cts.values()
- Example
- When to Choose op.fromLexicons()