-
-
Notifications
You must be signed in to change notification settings - Fork 43
Description
Environment
------------------------------
- Operating System: Linux
- Node Version: v16.14.2
- Nuxt Version: 3.4.2
- Nitro Version: 2.3.3
- Package Manager: npm@7.17.0
- Builder: vite
- User Config: -
- Runtime Modules: -
- Build Modules: -
------------------------------
Reproduction
https://stackblitz.com/edit/github-6qqdqu?file=app.vue,tsconfig.json
Describe the bug
When creating an entity with a composite primary key, it's impossible to find this entity by its key anymore.
Ideally this could be used to speedup the lookup process of some entities.
If you do repo.find('[id1,id2]'), it does find the correct ids in the first steps (storeFind), but will fail the where condition on the 2nd step (filterWhere). Shouldn't the id where be removed from the wheres clauses since it's already fulfilled in storeFind?
Additional context
I have an User, Community, and CommunityProfile. By using [community_id, user_id] I can quickly fetch the desired profile when I know both of them (which is almost always in my scenario).
Additionally, while digging through the code, I found that storeFind iterates over all the store entities looking for a specific id. Is this done intentionally? Wouldn't it be faster to iterate over the desired ids and check if they're on the store? Using an array there also seems slow:
Current implementation:
protected storeFind(ids: string[] = []): Collection<M> {
const data = this.commit('all')
const collection = [] as Collection<M>
for (const id in data) {
if (ids === undefined || ids.length === 0 || ids.includes(id))
collection.push(this.hydrate(data[id], { visible: this.visible, hidden: this.hidden, operation: 'get' }))
}
return collection
}
Alternative implementation 1 (single object lookup per id, much faster than iterating over all entities):
protected storeFind(ids: string[] = []): Collection<M> {
const data = this.commit('all')
const collection = [] as Collection<M>
const deduplicatedIds = new Set(ids && ids.length ? ids : [])
deduplicatedIds.forEach((id) => {
if (id in data)
collection.push(this.hydrate(data[id], { visible: this.visible, hidden: this.hidden, operation: 'get' }))
})
return collection
}
Alternative implementation 2 (preserve data order, a bit faster)
protected storeFind(ids: string[] = []): Collection<M> {
const data = this.commit('all')
const collection = [] as Collection<M>
const deduplicatedIds = new Set(ids && ids.length ? ids : [])
for (const id in data) {
if (deduplicatedIds.has(id))
collection.push(this.hydrate(data[id], { visible: this.visible, hidden: this.hidden, operation: 'get' }))
}
return collection
}
Logs
No response