File size: 6,931 Bytes
3932407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
import random

import pytest

from .helpers.collection_setup import drop_collection
from .helpers.helpers import request_with_validation


texts = [
    "2430 A.D.",
    "The Acquisitive Chuckle",
    "Author! Author!",
    "The Bicentennial Man",
    "Big Game",
    "The Billiard Ball",
    "Birth of a Notion",
    "Black Friar of the Flame",
    "Blank!",
    "Blind Alley",
    "Breeds There a Man...?",
    "Button, Button",
    "Buy Jupiter",
    "C-Chute",
    "Cal",
    "The Callistan Menace",
    "Catch That Rabbit",
    "Christmas on Ganymede",
    "Darwinian Pool Room",
    "Day of the Hunters",
    "Death Sentence",
    "Does a Bee Care?",
    "Dreaming Is a Private Thing",
    "The Dust of Death",
    "The Dying Night",
    "Each an Explorer",
    "Escape!",
    "Everest",
    "Evidence",
    "The Evitable Conflict",
    "Exile to Hell",
    "Eyes Do More Than See",
    "The Feeling of Power",
    "Feminine Intuition",
    "First Law",
    "Flies",
    "For the Birds",
    "Founding Father",
    "The Fun They Had",
    "Galley Slave",
    "The Gentle Vultures",
    "Getting Even",
    "Gimmicks Three",
    "Gold",
    "Good Taste",
    "The Greatest Asset",
    "Green Patches",
    "Half-Breed",
    "Half-Breeds on Venus",
    "Hallucination",
    "The Hazing",
    "Hell-Fire",
    "Heredity",
    "History",
    "Homo Sol",
    "Hostess",
    "I Just Make Them Up, See!",
    "I'm in Marsport Without Hilda",
    "The Imaginary",
    "The Immortal Bard",
    "In a Good Cause—",
    "Insert Knob A in Hole B",
    "The Instability",
    "It's Such a Beautiful Day",
    "The Key",
    "Kid Stuff",
    "The Last Answer",
    "The Last Question",
    "The Last Trump",
    "Left to Right",
    "Legal Rites",
    "Lenny",
    "Lest We Remember",
    "Let's Not",
    "Liar!",
    "Light Verse",
    "Little Lost Robot",
    "The Little Man on the Subway",
    "Living Space",
    "A Loint of Paw",
    "The Magnificent Possession",
    "Marching In",
    "Marooned off Vesta",
    "The Message",
    "Mirror Image",
    "Mother Earth",
    "My Son, the Physicist",
    "No Connection",
    "No Refuge Could Save",
    "Nobody Here But—",
    "Not Final!",
    "Obituary",
    "Old-fashioned",
    "Pâté de Foie Gras",
    "The Pause",
    "Ph as in Phony",
    "The Portable Star",
    "The Proper Study",
    "Rain, Rain, Go Away",
    "Reason",
    "The Red Queen's Race",
    "Rejection Slips",
    "Ring Around the Sun",
    "Risk",
    "Robot AL-76 Goes Astray",
    "Robot Dreams",
    "Runaround",
    "Sally",
    "Satisfaction Guaranteed",
    "The Secret Sense",
    "Shah Guido G.",
    "Silly Asses",
    "The Singing Bell",
    "Sixty Million Trillion Combinations",
    "Spell My Name with an S",
    "Star Light",
    "A Statue for Father",
    "Strikebreaker",
    "Super-Neutron",
    "Take a Match",
    "The Talking Stone",
    ". . . That Thou Art Mindful of Him",
    "Thiotimoline",
    "Time Pussy",
    "Trends",
    "Truth to Tell",
    "The Ugly Little Boy",
    "The Ultimate Crime",
    "Unto the Fourth Generation",
    "The Up-to-Date Sorcerer",
    "Waterclap",
    "The Watery Place",
    "The Weapon",
    "The Weapon Too Dreadful to Use",
    "What If—",
    "What Is This Thing Called Love?",
    "What's in a Name?",
    "The Winnowing",
]


def basic_collection_setup(
    collection_name='test_collection',
    on_disk_vectors=False,
    on_disk_payload=False,
):
    response = request_with_validation(
        api='/collections/{collection_name}',
        method="DELETE",
        path_params={'collection_name': collection_name},
    )
    assert response.ok

    response = request_with_validation(
        api='/collections/{collection_name}',
        method="PUT",
        path_params={'collection_name': collection_name},
        body={
            "vectors": {
                "size": 4,
                "distance": "Dot",
                "on_disk": on_disk_vectors,
            },
            "on_disk_payload": on_disk_payload,
        }
    )
    assert response.ok

    # Create index
    response = request_with_validation(
        api='/collections/{collection_name}/index',
        method="PUT",
        path_params={'collection_name': collection_name},
        query_params={'wait': 'true'},
        body={
            "field_name": "title",
            "field_schema": {
                "type": "text",
                "tokenizer": "prefix",
            }
        }
    )
    assert response.ok

    response = request_with_validation(
        api='/collections/{collection_name}',
        method="GET",
        path_params={'collection_name': collection_name},
    )
    assert response.ok

    response = request_with_validation(
        api='/collections/{collection_name}/points',
        method="PUT",
        path_params={'collection_name': collection_name},
        query_params={'wait': 'true'},
        body={
            "points": [
                {
                    "id": idx,
                    "vector": [random.random() for _ in range(4)],
                    "payload": {"title": title}
                } for idx, title in enumerate(texts)
            ]
        }
    )
    assert response.ok


@pytest.fixture(autouse=True, scope='module')
def setup(on_disk_vectors, on_disk_payload, collection_name):
    basic_collection_setup(collection_name=collection_name, on_disk_vectors=on_disk_vectors, on_disk_payload=on_disk_payload)
    yield
    drop_collection(collection_name=collection_name)


def test_scroll_with_prefix(collection_name):
    response = request_with_validation(
        api='/collections/{collection_name}/points/scroll',
        method="POST",
        path_params={'collection_name': collection_name},
        body={
            "offset": None,
            "limit": 10,
            "with_payload": True,
            "with_vector": False,
            "filter": {
                "should": [
                    {
                        "key": "title",
                        "match": {
                            "text": "ROBO",
                        }
                    }
                ]
            }
        }
    )

    assert response.ok
    assert len(response.json()['result']['points']) == 3

    response = request_with_validation(
        api='/collections/{collection_name}/points/search',
        method="POST",
        path_params={'collection_name': collection_name},
        body={
            "vector": [1., 1., 1., 1.],
            "limit": 10,
            "with_payload": True,
            "with_vector": False,
            "filter": {
                "should": [
                    {
                        "key": "title",
                        "match": {
                            "text": "ROBO",
                        }
                    }
                ]
            }
        }
    )

    assert response.ok
    assert len(response.json()['result']) == 3