Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

from vespa.package import Field
%load_ext autoreload
%autoreload 2
import json
import mycode.vap as vap
The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload
# The goal is to have a demo application that has 1M docs
# - numeric field
# - single dimension embedding field for the nearestNeighbor search
# - field string type for weakAnd
# Show that a natural way to write a query is not the fastest by presenting the query traces and compare how many documents are evaluated
app = vap.demo_application_package()
from vespa.package import Field
from vespa.package import QueryTypeField, QueryProfileType

app.get_schema("doc").add_fields(
    Field(
        name="embedding",
        type="tensor<float>(x[1])",
        indexing="attribute"
    ),
    Field(
        name="lexical",
        type="string",
        indexing="index",
        index="enable-bm25"
    ),
)

app.query_profile_type = QueryProfileType(
    fields=[
        QueryTypeField(
            name="ranking.features.query(query_embedding)",
            type="tensor<float>(x[1])"
        )
    ]
)

app.get_schema("doc").rank_profiles.pop("fields")
RankProfile('fields', '0', 'unranked', None, [Function('id', 'attribute(id)', None)], ['id'], ['id'], None, None, None, None, None, None, None, None, None, None, None)
print(app.get_schema("doc").schema_to_text)
schema doc {
    document doc {
        field id type int {
            indexing: attribute
            attribute {
                fast-search
            }
        }
        field embedding type tensor<float>(x[1]) {
            indexing: attribute
        }
        field lexical type string {
            indexing: index
            index: enable-bm25
        }
    }
}
from vespa.deployment import VespaDocker

# In case running colima on macos run the following
# !sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
vespa_docker = VespaDocker(
    container_image="vespaengine/vespa:8.672.3",
)
# Start a docker container and deploy the application package
client = vespa_docker.deploy(
    application_package=app,
)
Waiting for configuration server, 0/60 seconds...
Waiting for configuration server, 5/60 seconds...
Application is up!
Finished deployment.
vap.redeploy(vespa_docker, app)
Deploy status code: 200
Vespa(http://localhost, 8080)
import random


def simulate_text():
    """
    Pics a random number of words from random numbers from 0 to 30000.
    Joins them in to a string.
    :return:
    """
    dictionary_size = 30001
    num_words = random.randint(1, 20)
    return " ".join(map(lambda n: str(n), random.sample(range(dictionary_size), num_words)))


def simulate_embedding():
    return [random.uniform(0, 1)]
simulate_text()
'1678 27763 4868 19582 12785 2253 25472 26042 1961 3405 1003 221 22113'
vap.feed(
    client=client,
    docs=[
        {
            "id": i,
            "embedding": simulate_embedding(),
            "lexical": simulate_text()
        } for i in range(100000)],
)
yql_base = """
SELECT *
FROM sources *
WHERE
 (id> 1)
 AND (
   ({targetHits: 1000, approximate: false}nearestNeighbor(embedding, query_embedding))
   OR
   ({targetHits: 1000, defaultIndex: "lexical"}userInput(@query_str))
  )
"""
print(yql_base)

SELECT *
FROM sources *
WHERE
 (id> 1)
 AND (
   ({targetHits: 1000, approximate: false}nearestNeighbor(embedding, query_embedding))
   OR
   ({targetHits: 1000, defaultIndex: "lexical"}userInput(@query_str))
  )

request = {
    "yql": yql_base,
    "query_str": "27110 6334 10140 22335 22040 2716",
    "input.query(query_embedding)": [0.5],
    "presentation.timing": True,
    "hits": 1,
}
print(json.dumps(client.query(body=request).json, indent=2))
{
  "root": {
    "children": [
      {
        "fields": {
          "documentid": "id:doc:doc::96960",
          "sddocname": "doc"
        },
        "id": "id:doc:doc::96960",
        "relevance": 0.24059506636028924,
        "source": "test_content"
      }
    ],
    "coverage": {
      "coverage": 100,
      "documents": 100000,
      "full": true,
      "nodes": 1,
      "results": 1,
      "resultsFull": 1
    },
    "fields": {
      "totalCount": 5692
    },
    "id": "toplevel",
    "relevance": 1.0
  },
  "timing": {
    "querytime": 0.012,
    "searchtime": 0.013000000000000001,
    "summaryfetchtime": 0.0
  }
}
# Good we've found ~5692 docs
# Now let's try with tracing and ask vespa CLI to summarize the trace
import mycode.trace as trace
resp_base = client.query(body=trace.add_trace(request)).json
print(trace.inspect_trace(resp_base))
┌─────────┬───────────┐
│ total   │ 96.000 ms │
├─────────┼───────────┤
│ query   │ 94.000 ms │
│ summary │  1.000 ms │
│ other   │  1.000 ms │
└─────────┴───────────┘
found 1 search
┌────────┬───────┬───────────────┬───────────────┐
│ search │ nodes │ back-end time │ document type │
├────────┼───────┼───────────────┼───────────────┤
│      0 │     1 │     89.984 ms │ doc           │
└────────┴───────┴───────────────┴───────────────┘
looking into search #0
slowest node was: doc[0]: 89.984 ms
┌───────────────┬───────────┐
│ task          │ doc[0]    │
├───────────────┼───────────┤
│ global filter │  0.000 ms │
│ ann setup     │  0.000 ms │
│ matching      │ 85.378 ms │
│ first phase   │  2.538 ms │
│ second phase  │  0.000 ms │
└───────────────┴───────────┘
looking into node doc[0]
┌───────────┬─────────────────────────────────────────────────────────────┐
│ timestamp │ event                                                       │
├───────────┼─────────────────────────────────────────────────────────────┤
│  0.103 ms │ searching for 10 hits at offset 0                           │
│  0.131 ms │ Start query setup                                           │
│  0.133 ms │ Deserialize and build query tree                            │
│  0.150 ms │ Build query execution plan                                  │
│  0.272 ms │ Optimize query execution plan                               │
│  0.286 ms │ Perform dictionary lookups and posting lists initialization │
│  0.697 ms │ Prepare shared state for multi-threaded rank executors      │
│  0.719 ms │ Complete query setup                                        │
│           │ (query execution happens here, analyzed below)              │
│ 89.983 ms │ returning 10 hits from total 5692                           │
└───────────┴─────────────────────────────────────────────────────────────┘
ann query details (total setup time was 0.000 ms)
┌─────────────────────────┬─────────────────────┐
│ property                │ details             │
├─────────────────────────┼─────────────────────┤
│ attribute tensor        │ tensor<float>(x[1]) │
│ query tensor            │ tensor<float>(x[1]) │
│ target hits             │                1000 │
│ explore additional hits │                   0 │
│ algorithm               │ exact               │
│ global filter           │ not calculated      │
└─────────────────────────┴─────────────────────┘
found 1 thread
slowest matching and ranking was thread #0: 87.915 ms
┌──────────────┬───────────┐
│ task         │ thread #0 │
├──────────────┼───────────┤
│ matching     │ 85.378 ms │
│ first phase  │  2.538 ms │
│ second phase │  0.000 ms │
└──────────────┴───────────┘
looking into thread #0
┌───────────┬──────────────────────────────────┐
│ timestamp │ event                            │
├───────────┼──────────────────────────────────┤
│  0.891 ms │ Start MatchThread::run           │
│  0.999 ms │ Start match and first phase rank │
│ 89.783 ms │ Create result set                │
│ 89.797 ms │ Wait for result processing token │
│ 89.798 ms │ Start result processing          │
│ 89.867 ms │ Start thread merge               │
│ 89.868 ms │ MatchThread::run Done            │
└───────────┴──────────────────────────────────┘
match profiling for thread #0 (total time was 85.378 ms)
┌────────┬──────────┬─────────┬──────┬────────────────────────────────────────────────┐
│ seeks  │ total_ms │ self_ms │ step │ query tree                                     │
├────────┼──────────┼─────────┼──────┼────────────────────────────────────────────────┤
│   5693 │   85.378 │   8.391 │ S    │  And[1]                                        │
│ 105690 │    2.628 │   2.435 │ S    │  ├── Attribute{int32,fs}[2] id:<range>         │
│  99998 │   72.503 │  11.457 │ N    │  ├── Or[3]                                     │
│ 100198 │    5.669 │   5.669 │ N    │  │   ├── NearestNeighbor[4]                    │
│  99998 │   55.377 │  32.596 │ N    │  │   └── WeakAnd[5]                            │
│  99998 │    3.765 │   3.752 │ N    │  │       ├── SourceBlender[6]                  │
│     37 │    0.013 │   0.013 │ N    │  │       │   └── MemoryTerm[7] lexical:27110   │
│  99998 │    3.929 │   3.915 │ N    │  │       ├── SourceBlender[8]                  │
│     24 │    0.013 │   0.013 │ N    │  │       │   └── MemoryTerm[9] lexical:6334    │
│  99998 │    3.771 │   3.747 │ N    │  │       ├── SourceBlender[10]                 │
│     29 │    0.024 │   0.024 │ N    │  │       │   └── MemoryTerm[11] lexical:10140  │
│  99998 │    3.660 │   3.637 │ N    │  │       ├── SourceBlender[12]                 │
│     36 │    0.023 │   0.023 │ N    │  │       │   └── MemoryTerm[13] lexical:22335  │
│  99998 │    3.985 │   3.952 │ N    │  │       ├── SourceBlender[14]                 │
│     58 │    0.034 │   0.034 │ N    │  │       │   └── MemoryTerm[15] lexical:22040  │
│  99998 │    3.671 │   3.658 │ N    │  │       └── SourceBlender[16]                 │
│     33 │    0.012 │   0.012 │ N    │  │           └── MemoryTerm[17] lexical:2716   │
│  99999 │    2.242 │   2.049 │ N    │  └── WhiteList[18]                             │
└────────┴──────────┴─────────┴──────┴────────────────────────────────────────────────┘
first phase rank profiling for thread #0 (total time was 2.538 ms)
┌───────┬─────────┬───────────────────────────────────┐
│ count │ self_ms │ component                         │
├───────┼─────────┼───────────────────────────────────┤
│  5692 │   1.003 │ rank feature nativeProximity      │
│  5692 │   0.829 │ rank feature nativeRank           │
│  5692 │   0.471 │ rank feature nativeFieldMatch     │
│  5692 │   0.234 │ rank feature nativeAttributeMatch │
└───────┴─────────┴───────────────────────────────────┘

print(trace.get_matching_summary(trace.inspect_trace(resp_base)))
match profiling for thread #0 (total time was 91.847 ms)
┌────────┬──────────┬─────────┬──────┬────────────────────────────────────────────────┐
│ seeks  │ total_ms │ self_ms │ step │ query tree                                     │
├────────┼──────────┼─────────┼──────┼────────────────────────────────────────────────┤
│   5693 │   91.847 │   9.503 │ S    │  And[1]                                        │
│ 105690 │    2.840 │   2.628 │ S    │  ├── Attribute{int32,fs}[2] id:<range>         │
│  99998 │   77.513 │  12.364 │ N    │  ├── Or[3]                                     │
│ 100198 │    6.139 │   6.139 │ N    │  │   ├── NearestNeighbor[4]                    │
│  99998 │   59.010 │  35.133 │ N    │  │   └── WeakAnd[5]                            │
│  99998 │    3.928 │   3.906 │ N    │  │       ├── SourceBlender[6]                  │
│     37 │    0.022 │   0.022 │ N    │  │       │   └── MemoryTerm[7] lexical:27110   │
│  99998 │    3.959 │   3.944 │ N    │  │       ├── SourceBlender[8]                  │
│     24 │    0.015 │   0.015 │ N    │  │       │   └── MemoryTerm[9] lexical:6334    │
│  99998 │    4.027 │   4.014 │ N    │  │       ├── SourceBlender[10]                 │
│     29 │    0.013 │   0.013 │ N    │  │       │   └── MemoryTerm[11] lexical:10140  │
│  99998 │    4.046 │   4.027 │ N    │  │       ├── SourceBlender[12]                 │
│     36 │    0.019 │   0.019 │ N    │  │       │   └── MemoryTerm[13] lexical:22335  │
│  99998 │    3.967 │   3.939 │ N    │  │       ├── SourceBlender[14]                 │
│     58 │    0.027 │   0.027 │ N    │  │       │   └── MemoryTerm[15] lexical:22040  │
│  99998 │    3.951 │   3.939 │ N    │  │       └── SourceBlender[16]                 │
│     33 │    0.012 │   0.012 │ N    │  │           └── MemoryTerm[17] lexical:2716   │
│  99999 │    2.416 │   2.204 │ N    │  └── WhiteList[18]                             │
└────────┴──────────┴─────────┴──────┴────────────────────────────────────────────────┘

# Above we see that weakAnd evaluated 99998 docs, which means that it can't prune matches.
# Now let's rewrite the query
yql_alt = """
SELECT *
FROM sources *
WHERE
  (id> 1 AND ({targetHits: 1000, approximate: false}
              nearestNeighbor(embedding, query_embedding))
  OR
  (id> 1 AND ({targetHits: 1000, defaultIndex: "lexical"}userInput(@query_str))))
"""
print(yql_alt)

SELECT *
FROM sources *
WHERE
  (id> 1 AND ({targetHits: 1000, approximate: false}
              nearestNeighbor(embedding, query_embedding))
  OR
  (id> 1 AND ({targetHits: 1000, defaultIndex: "lexical"}userInput(@query_str))))

client.query(body={
    **request,
    "yql": yql_alt,
}).json
{'root': {'children': [{'fields': {'documentid': 'id:doc:doc::96960', 'sddocname': 'doc'}, 'id': 'id:doc:doc::96960', 'relevance': 0.24030457979529288, 'source': 'test_content'}], 'coverage': {'coverage': 100, 'documents': 100000, 'full': True, 'nodes': 1, 'results': 1, 'resultsFull': 1}, 'fields': {'totalCount': 5692}, 'id': 'toplevel', 'relevance': 1.0}, 'timing': {'querytime': 0.007, 'searchtime': 0.009000000000000001, 'summaryfetchtime': 0.0}}
resp_alt = client.query(body={
    **trace.add_trace(request),
    "yql": yql,
}).json
print(trace.inspect_trace(resp_alt))
┌─────────┬───────────┐
│ total   │ 35.000 ms │
├─────────┼───────────┤
│ query   │ 33.000 ms │
│ summary │  1.000 ms │
│ other   │  1.000 ms │
└─────────┴───────────┘
found 1 search
┌────────┬───────┬───────────────┬───────────────┐
│ search │ nodes │ back-end time │ document type │
├────────┼───────┼───────────────┼───────────────┤
│      0 │     1 │     26.625 ms │ doc           │
└────────┴───────┴───────────────┴───────────────┘
looking into search #0
slowest node was: doc[0]: 26.625 ms
┌───────────────┬───────────┐
│ task          │ doc[0]    │
├───────────────┼───────────┤
│ global filter │  0.000 ms │
│ ann setup     │  0.000 ms │
│ matching      │ 21.827 ms │
│ first phase   │  2.696 ms │
│ second phase  │  0.000 ms │
└───────────────┴───────────┘
looking into node doc[0]
┌───────────┬─────────────────────────────────────────────────────────────┐
│ timestamp │ event                                                       │
├───────────┼─────────────────────────────────────────────────────────────┤
│  0.096 ms │ searching for 1 hits at offset 0                            │
│  0.117 ms │ Start query setup                                           │
│  0.119 ms │ Deserialize and build query tree                            │
│  0.138 ms │ Build query execution plan                                  │
│  0.236 ms │ Optimize query execution plan                               │
│  0.248 ms │ Perform dictionary lookups and posting lists initialization │
│  0.753 ms │ Prepare shared state for multi-threaded rank executors      │
│  0.780 ms │ Complete query setup                                        │
│           │ (query execution happens here, analyzed below)              │
│ 26.623 ms │ returning 1 hits from total 5692                            │
└───────────┴─────────────────────────────────────────────────────────────┘
ann query details (total setup time was 0.000 ms)
┌─────────────────────────┬─────────────────────┐
│ property                │ details             │
├─────────────────────────┼─────────────────────┤
│ attribute tensor        │ tensor<float>(x[1]) │
│ query tensor            │ tensor<float>(x[1]) │
│ target hits             │                1000 │
│ explore additional hits │                   0 │
│ algorithm               │ exact               │
│ global filter           │ not calculated      │
└─────────────────────────┴─────────────────────┘
found 1 thread
slowest matching and ranking was thread #0: 24.523 ms
┌──────────────┬───────────┐
│ task         │ thread #0 │
├──────────────┼───────────┤
│ matching     │ 21.827 ms │
│ first phase  │  2.696 ms │
│ second phase │  0.000 ms │
└──────────────┴───────────┘
looking into thread #0
┌───────────┬──────────────────────────────────┐
│ timestamp │ event                            │
├───────────┼──────────────────────────────────┤
│  0.844 ms │ Start MatchThread::run           │
│  0.933 ms │ Start match and first phase rank │
│ 26.419 ms │ Create result set                │
│ 26.433 ms │ Wait for result processing token │
│ 26.434 ms │ Start result processing          │
│ 26.510 ms │ Start thread merge               │
│ 26.510 ms │ MatchThread::run Done            │
└───────────┴──────────────────────────────────┘
match profiling for thread #0 (total time was 21.827 ms)
┌───────┬──────────┬─────────┬──────┬────────────────────────────────────────────────────┐
│ seeks │ total_ms │ self_ms │ step │ query tree                                         │
├───────┼──────────┼─────────┼──────┼────────────────────────────────────────────────────┤
│  5693 │   21.827 │   1.129 │ S    │  And[1]                                            │
│  5693 │   20.494 │   0.914 │ S    │  ├── Or[2]                                         │
│  5492 │   19.203 │   9.370 │ S    │  │   ├── And[3]                                    │
│ 99998 │    3.764 │   3.764 │ S    │  │   │   ├── Attribute{int32,fs}[4] id:<range>     │
│ 99998 │    6.070 │   6.070 │ N    │  │   │   └── NearestNeighbor[5]                    │
│   213 │    0.377 │   0.059 │ S    │  │   └── And[6]                                    │
│   213 │    0.249 │   0.073 │ S    │  │       ├── WeakAnd[7]                            │
│    38 │    0.027 │   0.013 │ S    │  │       │   ├── SourceBlender[8]                  │
│    37 │    0.014 │   0.014 │ S    │  │       │   │   └── MemoryTerm[9] lexical:27110   │
│    25 │    0.027 │   0.016 │ S    │  │       │   ├── SourceBlender[10]                 │
│    24 │    0.012 │   0.012 │ S    │  │       │   │   └── MemoryTerm[11] lexical:6334   │
│    30 │    0.022 │   0.011 │ S    │  │       │   ├── SourceBlender[12]                 │
│    29 │    0.011 │   0.011 │ S    │  │       │   │   └── MemoryTerm[13] lexical:10140  │
│    37 │    0.026 │   0.013 │ S    │  │       │   ├── SourceBlender[14]                 │
│    36 │    0.013 │   0.013 │ S    │  │       │   │   └── MemoryTerm[15] lexical:22335  │
│    59 │    0.047 │   0.023 │ S    │  │       │   ├── SourceBlender[16]                 │
│    58 │    0.024 │   0.024 │ S    │  │       │   │   └── MemoryTerm[17] lexical:22040  │
│    34 │    0.028 │   0.017 │ S    │  │       │   └── SourceBlender[18]                 │
│    33 │    0.011 │   0.011 │ S    │  │       │       └── MemoryTerm[19] lexical:2716   │
│   212 │    0.069 │   0.069 │ N    │  │       └── Attribute{int32,fs}[20] id:<range>    │
│  5692 │    0.204 │   0.204 │ N    │  └── WhiteList[21]                                 │
└───────┴──────────┴─────────┴──────┴────────────────────────────────────────────────────┘
first phase rank profiling for thread #0 (total time was 2.696 ms)
┌───────┬─────────┬───────────────────────────────────┐
│ count │ self_ms │ component                         │
├───────┼─────────┼───────────────────────────────────┤
│  5692 │   1.001 │ rank feature nativeProximity      │
│  5692 │   0.937 │ rank feature nativeRank           │
│  5692 │   0.519 │ rank feature nativeFieldMatch     │
│  5692 │   0.240 │ rank feature nativeAttributeMatch │
└───────┴─────────┴───────────────────────────────────┘

print(trace.get_matching_summary(trace.inspect_trace(resp_alt)))
match profiling for thread #0 (total time was 21.827 ms)
┌───────┬──────────┬─────────┬──────┬────────────────────────────────────────────────────┐
│ seeks │ total_ms │ self_ms │ step │ query tree                                         │
├───────┼──────────┼─────────┼──────┼────────────────────────────────────────────────────┤
│  5693 │   21.827 │   1.129 │ S    │  And[1]                                            │
│  5693 │   20.494 │   0.914 │ S    │  ├── Or[2]                                         │
│  5492 │   19.203 │   9.370 │ S    │  │   ├── And[3]                                    │
│ 99998 │    3.764 │   3.764 │ S    │  │   │   ├── Attribute{int32,fs}[4] id:<range>     │
│ 99998 │    6.070 │   6.070 │ N    │  │   │   └── NearestNeighbor[5]                    │
│   213 │    0.377 │   0.059 │ S    │  │   └── And[6]                                    │
│   213 │    0.249 │   0.073 │ S    │  │       ├── WeakAnd[7]                            │
│    38 │    0.027 │   0.013 │ S    │  │       │   ├── SourceBlender[8]                  │
│    37 │    0.014 │   0.014 │ S    │  │       │   │   └── MemoryTerm[9] lexical:27110   │
│    25 │    0.027 │   0.016 │ S    │  │       │   ├── SourceBlender[10]                 │
│    24 │    0.012 │   0.012 │ S    │  │       │   │   └── MemoryTerm[11] lexical:6334   │
│    30 │    0.022 │   0.011 │ S    │  │       │   ├── SourceBlender[12]                 │
│    29 │    0.011 │   0.011 │ S    │  │       │   │   └── MemoryTerm[13] lexical:10140  │
│    37 │    0.026 │   0.013 │ S    │  │       │   ├── SourceBlender[14]                 │
│    36 │    0.013 │   0.013 │ S    │  │       │   │   └── MemoryTerm[15] lexical:22335  │
│    59 │    0.047 │   0.023 │ S    │  │       │   ├── SourceBlender[16]                 │
│    58 │    0.024 │   0.024 │ S    │  │       │   │   └── MemoryTerm[17] lexical:22040  │
│    34 │    0.028 │   0.017 │ S    │  │       │   └── SourceBlender[18]                 │
│    33 │    0.011 │   0.011 │ S    │  │       │       └── MemoryTerm[19] lexical:2716   │
│   212 │    0.069 │   0.069 │ N    │  │       └── Attribute{int32,fs}[20] id:<range>    │
│  5692 │    0.204 │   0.204 │ N    │  └── WhiteList[21]                                 │
└───────┴──────────┴─────────┴──────┴────────────────────────────────────────────────────┘

# above we see that weakAnd evaluated only 213 docs
# Which resulted in significantly lower latency: from ~100ms down to ~35ms.
print(trace.get_matching_summary(trace.inspect_trace(resp_alt)))
match profiling for thread #0 (total time was 21.827 ms)
┌───────┬──────────┬─────────┬──────┬────────────────────────────────────────────────────┐
│ seeks │ total_ms │ self_ms │ step │ query tree                                         │
├───────┼──────────┼─────────┼──────┼────────────────────────────────────────────────────┤
│  5693 │   21.827 │   1.129 │ S    │  And[1]                                            │
│  5693 │   20.494 │   0.914 │ S    │  ├── Or[2]                                         │
│  5492 │   19.203 │   9.370 │ S    │  │   ├── And[3]                                    │
│ 99998 │    3.764 │   3.764 │ S    │  │   │   ├── Attribute{int32,fs}[4] id:<range>     │
│ 99998 │    6.070 │   6.070 │ N    │  │   │   └── NearestNeighbor[5]                    │
│   213 │    0.377 │   0.059 │ S    │  │   └── And[6]                                    │
│   213 │    0.249 │   0.073 │ S    │  │       ├── WeakAnd[7]                            │
│    38 │    0.027 │   0.013 │ S    │  │       │   ├── SourceBlender[8]                  │
│    37 │    0.014 │   0.014 │ S    │  │       │   │   └── MemoryTerm[9] lexical:27110   │
│    25 │    0.027 │   0.016 │ S    │  │       │   ├── SourceBlender[10]                 │
│    24 │    0.012 │   0.012 │ S    │  │       │   │   └── MemoryTerm[11] lexical:6334   │
│    30 │    0.022 │   0.011 │ S    │  │       │   ├── SourceBlender[12]                 │
│    29 │    0.011 │   0.011 │ S    │  │       │   │   └── MemoryTerm[13] lexical:10140  │
│    37 │    0.026 │   0.013 │ S    │  │       │   ├── SourceBlender[14]                 │
│    36 │    0.013 │   0.013 │ S    │  │       │   │   └── MemoryTerm[15] lexical:22335  │
│    59 │    0.047 │   0.023 │ S    │  │       │   ├── SourceBlender[16]                 │
│    58 │    0.024 │   0.024 │ S    │  │       │   │   └── MemoryTerm[17] lexical:22040  │
│    34 │    0.028 │   0.017 │ S    │  │       │   └── SourceBlender[18]                 │
│    33 │    0.011 │   0.011 │ S    │  │       │       └── MemoryTerm[19] lexical:2716   │
│   212 │    0.069 │   0.069 │ N    │  │       └── Attribute{int32,fs}[20] id:<range>    │
│  5692 │    0.204 │   0.204 │ N    │  └── WhiteList[21]                                 │
└───────┴──────────┴─────────┴──────┴────────────────────────────────────────────────────┘

yql_and = """
           SELECT *
           FROM sources *
           WHERE
               (id> 1)
             AND (
               ({targetHits: 1000, approximate: false}nearestNeighbor(embedding, query_embedding))
              OR
               ({targetHits: 1000, defaultIndex: "lexical", grammar: "all"}userInput(@query_str))
               )
           """
request = {
    "yql": yql_and,
    "query_str": "27110 6334 10140 22335 22040 2716",
    "input.query(query_embedding)": [0.5],
    "presentation.timing": True,
    "hits": 1,
}
client.query(body=request).json
{'root': {'children': [{'fields': {'documentid': 'id:doc:doc::96960', 'sddocname': 'doc'}, 'id': 'id:doc:doc::96960', 'relevance': 0.24059506636028924, 'source': 'test_content'}], 'coverage': {'coverage': 100, 'documents': 100000, 'full': True, 'nodes': 1, 'results': 1, 'resultsFull': 1}, 'fields': {'totalCount': 5493}, 'id': 'toplevel', 'relevance': 1.0}, 'timing': {'querytime': 0.007, 'searchtime': 0.008, 'summaryfetchtime': 0.0}}
yql_no_filters = """
          select *
          from sources *
          where (
              ({targetHits: 1000, approximate: false}nearestNeighbor(embedding, query_embedding))
             OR
              ({targetHits: 1000, defaultIndex: "lexical"}userInput(@query_str))
              )
          """
request = {
    **trace.add_trace(request),
    "yql": yql_no_filters,
    "query_str": "27110 6334 10140 22335 22040 2716",
    "input.query(query_embedding)": [0.5],
    "presentation.timing": True,
    "hits": 1,
}
resp_no_filters = client.query(body=request).json
resp_no_filters
print(trace.get_matching_summary(trace.inspect_trace(resp_no_filters)))
match profiling for thread #0 (total time was 4.903 ms)
┌───────┬──────────┬─────────┬──────┬────────────────────────────────────────────────┐
│ seeks │ total_ms │ self_ms │ step │ query tree                                     │
├───────┼──────────┼─────────┼──────┼────────────────────────────────────────────────┤
│  5691 │    4.903 │   1.046 │ S    │  And[1]                                        │
│  5691 │    3.670 │   0.942 │ S    │  ├── Or[2]                                     │
│  5491 │    1.762 │   1.762 │ S    │  │   ├── NearestNeighbor[3]                    │
│   213 │    0.965 │   0.059 │ S    │  │   └── WeakAnd[4]                            │
│    38 │    0.126 │   0.009 │ S    │  │       ├── SourceBlender[5]                  │
│    37 │    0.116 │   0.116 │ S    │  │       │   └── MemoryTerm[6] lexical:27110   │
│    25 │    0.121 │   0.011 │ S    │  │       ├── SourceBlender[7]                  │
│    24 │    0.109 │   0.109 │ S    │  │       │   └── MemoryTerm[8] lexical:6334    │
│    30 │    0.125 │   0.015 │ S    │  │       ├── SourceBlender[9]                  │
│    29 │    0.109 │   0.109 │ S    │  │       │   └── MemoryTerm[10] lexical:10140  │
│    37 │    0.156 │   0.020 │ S    │  │       ├── SourceBlender[11]                 │
│    36 │    0.136 │   0.136 │ S    │  │       │   └── MemoryTerm[12] lexical:22335  │
│    59 │    0.233 │   0.013 │ S    │  │       ├── SourceBlender[13]                 │
│    58 │    0.220 │   0.220 │ S    │  │       │   └── MemoryTerm[14] lexical:22040  │
│    34 │    0.146 │   0.012 │ S    │  │       └── SourceBlender[15]                 │
│    33 │    0.133 │   0.133 │ S    │  │           └── MemoryTerm[16] lexical:2716   │
│  5690 │    0.187 │   0.187 │ N    │  └── WhiteList[17]                             │
└───────┴──────────┴─────────┴──────┴────────────────────────────────────────────────┘