Fork me on GitHub

Is there a good pattern for doing a datomic query where one of the params might not be given, and if it’s not given, does not constrain the query? For instance, I might want to query for people with a given name and possibly also a birthdate. I’ve done this before by using the map query form and adding clauses and params, but it feels like I’m swimming against the tide.


You could use a rule which handles nil maybe


You can’t pass a nil value in, though you could pass in e.g. an empty set, or a ::missing sentinel value that can’t appear in your corpus. I’m just having trouble expressing an or rule that unites correctly. Currently I’m just punting on doing it in q and filtering the results which is… fine, it just feels like a common-ish query need for which I lack a pattern.


having spent only a few days with datomic, but a lot of time with spec, it seems silly to me to write a spec which essentially duplicates a schema. it gets especially “silly” feeling when my specs start referencing ids of other specs, much like a datomic ref. yet a few minutes after not having a spec i already wish i had s/conform available to me. how are people handling this? generating specs from schema, or vice versa?


specs don't duplicate the schema


specs can express much more


yes, I agree they’re really powerful. maybe i haven’t figured out in my own head what i dont like about a schema right next to a spec. perhaps it’s that much like datomic entities can have different contexts and aggregate attributes accordingly (a person can be a user, or a client), specs have to do the same thing. and i think I just don’t like all that near-identicalness? .. just musing i suppose


there's probably some fundamental concerns/functionality of a Datomic schema and a spec (after all, they're both describing collections of data, usually, and information about the problem domain you are solving), but it might be harder to tease out their true nature enough to build an abstraction to share them

👍 4

FWIW, we've been using this for about a year now, and it's been working nicely:

❤️ 8

when modeling attributes related to time (usually a lot of entities deal with things like created, updated, etc) what’s a general approach? attrs like updated seem unnecessary due to the information model. but what about if you had two entities A and B, where both have a start-date and end-date? is it better to model these idents as :time/start-date, :time/end-date or more specific to the entity? :a/start-date, :b/start-date, ... etc?


on one hand i feel like a particular entity might in the future be modeled as an aggregate like :a/start-date, b/start-date in which case separate idents makes sense. but i’m not sure if this is ever really going to happen, and i’m not quite sure what the disadvantages are for this kind of model.


This is actually something I've been thinking about a lot lately. There's this natural tension when defining a spec or schema between "what's the most generic, open-ended thing I can assert about this granular value?" and "what do I want to say/guarantee about this value in a certain context? (eg when it's attached to an entity)?"


This: got me thinking about the cases where you might be able to do both. The trouble is that Datomic schema does more than just define structural properties of the value itself, it also says things about how the [attr value] pair relates to the containing collection, such as uniqueness/identity.


The case I was thinking about was something like :email vs :. I wanted to be able to say both things about the (string) value itself.


Now that I'm writing that though, I realize that perhaps this is a good chance to pick up a multimethod or Datalog rule to express a relationship, something like "all : qualify as :email, but the reverse may not hold"


multimethods seem like a more extensible strategy there. they’re defined in the app code, whereas a rule may or may not hold true in the context of another app using the same db? maybe?


Depends on where that logical deduction needs to take place I guess


but delaying the decision and moving it out of the schema buys you flexibility. I think this is the "a-la-cart" polymorphism Rich is always mentioning. You just decide what things should count as "the same" when you define the operations/actions you need to perform with them.


as always in the clj ecosystem, so much to think about. the more you learn the more you realize there’s better ways to do everything.


Yep. That's why it's a programmer's dreamland.


I've felt similarly, but I think it comes down to the Clojure community bias towards decomplecting, even if convenience or short term experience makes it seem like two things are "the same"

👍 4