Comments (21)
I'm going to re-open this to track adding some better slice query options. Off the top of my head I'm thinking:
Where("SliceField").ContainsAny(value1, value2, value3)
Where("SliceField").ContainsAll(value1, value2, value3)
Any other ideas?
from bolthold.
Either Contains
or ContainsAll
sounds reasonable. That said, while ContainsAll
is more explicit in indicating what is being checked, it does read a bit awkwardly when only checking for a single value. So, I think you could make a case for all three variants (Contains
, ContainsAll
, and ContainsAny
).
from bolthold.
from bolthold.
SubQuery wouldn't be useful in this situation. Subquery would be useful if you wanted to run another separate query for each of the results of the MatchFuncQuery.
Using the comparer interface would remove the need for hte loop, but that same loop is essentially happening in the .In(...)
query criteria, so go which whichever is clearer.
from bolthold.
from bolthold.
Makes sense - thanks!
from bolthold.
I was precisely looking for this functionality.
Its not so clear what ContainsAll means. is it like an hypothetic ContainsSome or is a somehow "stricter" equality ?
from bolthold.
@mh-cbon I was trying to match the strings package. They have .Contains
and .ContainsAny
. I thought ContainsAll
was clearer than just Contains
val := struct {
Set []string
}{
Set: []string{"1", "2", "3"},
}
bh.Where("Set").ContainsAll("1", "3") //true
bh.Where("Set").ContainsAll("1", "3", "4") //false
bh.Where("Set").ContainsAny("1", "7", "4") //true
Maybe it'll be simpler and clearer to only have .Contains
that accepts one value, and people can use and / or to do the same:
val := struct {
Set []string
}{
Set: []string{"1", "2", "3"},
}
bh.Where("Set").Contains("1").And("Set").Contains("3") //true
bh.Where("Set").Contains("1").And("Set").Contains("3").And("Set").Contains("4") //false
bh.Where("Set").Contains("1").Or(bh.Where("Set").Contains("7")).Or(bh.Where("Set").Contains("4")) //true
More verbose, but clearer, which is guess in the end is more like idiomatic Go. After typing all of that up, I'm leaning towards this 2nd option.
Thoughts?
from bolthold.
Why don't have both option? Contains for single parameter and ContainsAny{All} for several?
from bolthold.
I would expect having even more options would make things even less clear. The fact the @mh-cbon was confused that ContainsAll
means the wording I chose was less than clear.
from bolthold.
second option is no-go in my opinion it just makes things harder.
First version is much better, it makes sense with insights about the design.
However, does the lib handle a strict Eq equality over basics slice types ? I mean does the And(f).Eq([]T{1,2,3})
works and returns true ? That was what bothered me about the {All}, at first i could not determine how it behaves in comparison to Eq.
from bolthold.
from bolthold.
Also, @mh-cbon what specifically is "harder". That you have to type more or that it's less clear?
from bolthold.
both. harder to read, harder to build. It does not look like a good api. the first version was unclear to me at first, but that is what documentation and examples are made for.
from bolthold.
Is ContainsEach("1", "2", "3")
clearer than ContainsAll("1","2", "3")
?
from bolthold.
I think ContainsAll / ContainsAny are perfect.
from bolthold.
FYI, when using Contains/All/Any on a value other than a slice, I plan on simply not matching instead of returning a error.
from bolthold.
Details are in the README:
https://github.com/timshannon/bolthold#slices-in-structs-and-queries
from bolthold.
What if the slice's values are not primitives, but structs again, whose fields I want to compare to?
For instance, assume the above example is modified like this:
type Tag struct {
Id int,
Name string
}
// [...]
ItemTest{
Key: 1,
ID: 32,
Name: "pizza",
Tags: []Tag{Tag{Id: 1, Name: "cheese"}, Tag{Id: 2, Name: "sausage"}},
}
// [...]
Probably I can use .MatchFunc()
for this, but I'm not sure how. Could somebody please give me a little support?
from bolthold.
Yeah Match Func would work, or you could implement the Comparer
interface on your Tag struct:
func (t Tag) Compare(other interface{}) (int, error) {
if t.Id == other.(Tag).Id {
return 0, nil
}
if t.Id < other.(Tag).Id {
return -1, nil
}
return 1, nil
}
The code above assumes you want to compare based on Tag ID.
from bolthold.
Very cool, thanks! I achieved what I wanted with MatchFunc
using the following code.
q.Where("Tags").MatchFunc(func(ra *bolthold.RecordAccess) (bool, error) {
if field := ra.Field(); field != nil {
for _, item := range field.([]*Tag) {
if item.Id == "foo" {
return true, nil
}
}
return false, nil
}
})
However, I was wondering if I could also use .SubQuery()
instead of manually iterating the slice. Could you provide some minimal documentation for that?
from bolthold.
Related Issues (20)
- 如何查询某个bucket的全部数据 HOT 1
- his error occurs when fetching data from a specific bucket HOT 8
- readme.md: boltholdIndex, boltHoldIndex HOT 4
- Upsert with custom Storer delivers inconsistent value type to index function HOT 2
- Multiple calls to Delete for non-existing key result in EOF error instead of ErrNotFound HOT 2
- Add method to wrap existing bolt instance HOT 1
- Q: limit query without conditions HOT 2
- Unique index
- Can't sort by PK HOT 1
- Add support for batch inserts HOT 2
- Distinct constraint HOT 2
- Get vs FindOne HOT 9
- Web UI
- Aggregate query on nested struct HOT 2
- Constraint pairs HOT 1
- Slow write speeds HOT 7
- Initialise read only store HOT 2
- foreach can't use, when the key's type is uint64 HOT 1
- SliceIndex query ContainsAll not working HOT 6
- Sort by primary key has no effect seemingly HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bolthold.