You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: search/implement_elasticseach.md
+33-1
Original file line number
Diff line number
Diff line change
@@ -347,4 +347,36 @@ class SearchableMixin(object):
347
347
348
348
The `search()` function uses a class method to associate it with a given class rather than a particular instance. Instead of using `self` as is normally the case with a class, notice how I use the `cls` to make it clear that this method receives a class and not an instance as its first argument. Once it is attached to a model, say the `Post` model, the search method will be invocked as `Post.search()` without needing an actual instance of the class `Post`.
349
349
350
-
To begin, you will notice that the `cls.__tablename__` is passed to `query_index` as the index name. This is going to be a convention such that the names assigned by SQLAlchemy to a model shall be used as the index name.
350
+
To begin, you will notice that the `cls.__tablename__` is passed to `query_index` as the index name. This is going to be a convention such that the names assigned by SQLAlchemy to a model shall be used as the index name. The returned query is a **series of positional elements** (rather than a list) and their total number. We have used `case` from SQLAlchemy to retrieve the list of objects by their IDs in the order they were given. This is so because Elasticsearch returns a sorted query from more to less relevant.
351
+
352
+
> The CASE construct in SQL is a conditional object that acts somewhat analogously to an “if/then” construct in other languages. It returns an instance of `Case`. `case()` in its usual form is passed a series of “when” constructs, that is, a list of conditions and results as tuples:
353
+
354
+
```python
355
+
from sqlalchemy import case
356
+
357
+
stmt = select(users_table).\
358
+
where(
359
+
case(
360
+
(users_table.c.name =='wendy', 'W'),
361
+
(users_table.c.name =='jack', 'J'),
362
+
else_='E'
363
+
)
364
+
)
365
+
```
366
+
367
+
We loop through the list of IDs to retrieve their positions, which is what we pass to the `when` dictionary. Prior to Flask-SQLAlchemy V3.0.2, the `case()` method took a list rather than a dictionary. Instead of returning a series of positional elements, we'd get a list of objects by their IDs.
368
+
369
+
370
+
```python
371
+
classSearchableMixin(object):
372
+
@classmethod
373
+
defsearch(cls, expression, page, per_page):
374
+
# ...
375
+
when = []
376
+
for i inrange(len(ids)):
377
+
when.append((ids[i], i))
378
+
# ...
379
+
```
380
+
381
+
The latest version of Flask-sqlalchemy will return the error `sqlalchemy.exc.ArgumentError: The "whens" argument to case(), when referring to a sequence of items, is now passed as a series of positional elements, rather than as a list.` if a list is used.
0 commit comments