Readme update to include a few words on tags.

tag-rewrite
Karchnu 2024-04-26 23:28:36 +02:00
parent bcfe5d44d6
commit fce2b633ce
1 changed files with 39 additions and 28 deletions

View File

@ -162,25 +162,16 @@ $ tree storage/
...
└── tags
└── by_keyword
└── other-tags
├── average
│   ├── data
│   │   └── 0000000004.json -> ../../../../..//data/0000000004.json
...
├── dirty
│   ├── data
│   │   └── 0000000005.json -> ../../../../..//data/0000000005.json
...
├── elegant
│   ├── data
│   │   ├── 0000000000.json -> ../../../../..//data/0000000000.json
│   │   └── 0000000003.json -> ../../../../..//data/0000000003.json
├── elegant
│   ├── 0000000000.json -> ../../../data/0000000000.json
│   └── 0000000003.json -> ../../../data/0000000003.json
├── impressive
│   ├── 0000000000.json -> ../../../data/0000000000.json
│   ├── 0000000001.json -> ../../../data/0000000001.json
│   └── 0000000003.json -> ../../../data/0000000003.json
...
```
This is very similar to partitions, but there is a bit more complexity here since we eventually search for a car matching a combination of keywords.
**TODO**: explanations about our tag-based search and an example.
Tags are very similar to partitions and are used the exact same way for search, update and deletion.
## Updating an object
@ -204,23 +195,41 @@ cars_by_id.update "86a07924-ab3a-4f46-a975-e9803acba22d", car
Or, in the case the object may not yet exist:
```Crystal
cars_by_id.update_or_create car.id, car
# Search by partitions: all blue cars.
pp! cars_by_color.get "blue"
# Search by tags: all elegant cars.
pp! cars_by_keyword.get "elegant"
```
Changing a value that is related to a partition or a tag will automatically do what you would expect: de-index then re-index.
You won't find yourself with a bunch of invalid symbolic links all over the place.
## Removing an object
```Crystal
# Remove a value based on an index.
cars_by_id.delete "86a07924-ab3a-4f46-a975-e9803acba22d"
# Remove a value based on a partition.
cars_by_color.delete "red"
cars_by_color.delete "red", do |car|
cars_by_color.delete "blue", do |car|
car.keywords.empty
end
# Remove a value based on a tag.
cars_by_keyword.delete "shiny"
cars_by_keyword.delete "elegant", do |car|
car.name == "GTI"
end
```
In this last example, we apply the function on red cars only.
In this code snippet, we apply a function on blue cars only;
and blue cars are only removed if they don't have any associated keywords.
Same thing for elegant cars.
This represents a performance boost compared to applying the function on all the cars.
# Complete example
```Crystal
@ -292,11 +301,10 @@ pp! cars_by_name.get "Corvet"
# based on a partition (print all red cars)
pp! cars_by_color.get "red"
# based on a tag
# based on a tag (print all fast cars)
pp! cars_by_keyword.get "fast"
############
# Updating #
############
@ -314,7 +322,11 @@ cars_by_name.update "Bullet-GT", car # the name changed
car = Car.new "Mustang", "red", [] of String
cars_by_name.update_or_create car.name, car
# We all know it, elegant cars are also expensive.
cars_by_keyword.get("elegant").each do |car|
car.keywords << "expensive"
cars_by_name.update car.name, car
end
###############
# Deleting... #
@ -328,9 +340,8 @@ cars_by_color.delete "red"
# based on a color (but not only)
cars_by_color.delete "blue", &.name.==("GTI")
## TAG-based deletion, soon.
# # based on a keyword
# cars_by_keyword.delete "solid"
# # based on a keyword (but not only)
# cars_by_keyword.delete "fast", &.name.==("Corvet")
# based on a keyword
cars_by_keyword.delete "solid"
# based on a keyword (but not only)
cars_by_keyword.delete "fast", &.name.==("Corvet")
```