-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Best way of searching entity. #95
Comments
Thank you! We have big ideas for Graph :) Hmmm... 10 seconds seems really long. Can you share more about your setup and how you are currently searching? To search properties fastest, you can pull up the Entities with a given property and value, then filter further. Or you can choose the Type to search by and then filter. For example: let a: Array<Entity> = graph.searchForEntity(types: ["Type"]).filter { (entity: Entity) -> Bool in
return "Daniel" == entity["name"] as? String
}
let b: Array<Entity> = graph.searchForEntity(properties: [("name", "Daniel")]).filter { (entity: Entity) -> Bool in
return "Type" == entity.type
} The search could be combined and more complex. Mainly, it depends on your model and what you are trying to get out of the search. |
hey, thanks for the answer. The model I'm using is rather extensive, but for the purpose of the search only one property matters. Imagine an entity of type "Entry" which has a property named "unique". Imagine I have entered 350 unique entries. If I try to re-enter those same 350 entries, I have to check each of the entries I'm trying to add against the whole data base. I was looking for a way to retrieve the entity of type "entry" with the property "unique" = "something" with a single call (without using filter). Or at least the optimized way of doing that. Thanks for the help |
Graph doesn't support user made indices with unique keys yet. It does though, generate a unique key that can be used externally, or I can show you how to use Algorithm, which is a data structure library to achieve what you are looking for in log(n) time. A unique key feature is something I would be working on very soon. |
Okay :) How would algorithm apply in this case ? I would run it over the graph ? |
In Algorithm, there is a data structure called SortedDictionary. It has a key value pair, where the keys are kept sorted and the value is of any type you set. Using that data structure, below is a class called Index that monitors changes in Graph and always manages the collection of Entities that are being uniquely keyed. Keys in a SortedDictionary are kept unique by default. import Graph
import Algorithm
class Index<Key : Comparable where Key : Hashable>: GraphDelegate {
private var graph: Graph!
private(set) var dictionary: SortedDictionary<Key, Entity>!
init() {
prepareGraph()
prepareDictionary()
}
func find(key: Key) -> Entity? {
return dictionary.findValueForKey(key)
}
private func prepareGraph() {
graph = Graph()
graph.delegate = self
graph.watchForEntity(properties: ["unique"])
}
private func prepareDictionary() {
dictionary = SortedDictionary<Key, Entity>()
for entity in graph.searchForEntity(properties: [("unique", nil)]) {
if let key: Key = entity["unique"] as? Key {
dictionary.insert(key, value: entity)
}
}
}
@objc func graphDidInsertEntityProperty(graph: Graph, entity: Entity, property: String, value: AnyObject) {
if let v: Key = value as? Key {
dictionary.insert(v, value: entity)
}
}
@objc func graphDidUpdateEntityProperty(graph: Graph, entity: Entity, property: String, value: AnyObject) {
// If you need to handle key updates.
}
@objc func graphDidDeleteEntityProperty(graph: Graph, entity: Entity, property: String, value: AnyObject) {
if let v: Key = value as? Key {
dictionary.removeValueForKeys(v)
}
}
} To use it, you can do: let graph: Graph = Graph()
let keys: Array<String> = ["Jon", "Frank", "Sarah", "Susan"]
let index: Index<String> = Index<String>()
for key in keys {
var entity: Entity? = index.find(key)
if nil == entity {
entity = Entity(type: "Entry")
entity!["unique"] = key
}
}
graph.save() Using this approach you are only ever doing one search and one save. The comparison is done in log(n) because underlying the SortedDictionary is a RedBlackTree. If you insert new "Entry" type Entities, they will automatically be added to the Index as the changes in Graph are being watched through the watch API. |
Awesome!Many Thanks, this is helps me a lot. I Have only a minor doubt, why do you search for key unique with "nil" value in prepare for dictionary ? |
oh because when the value is set to nil, it searches all value types. You could do this as well, graph.searchForEntity(properties: [("unique", "*")])
graph.searchForEntity(properties: [(key: "unique", value: "*")]) where you are saying it is a String and that you wildcard the search. The nil, allows it to be any type. So if you know your keys are String then the |
I am going to close this issue for now, if you have any further questions, please reopen or create a new issue. Let me know how it worked out. All the best! |
Once I've implemented the solution I'll post my results :) thank for the help |
There are some tweaks you can make to use the solution across the board. If you need any help, let us know :) |
Hi, first off, I would like to say that I love the concept. I've been using it for a few days and I would like to ask if there is an optimized way that you'd recommend for searching for a specific entity with a specific property. I've been time profiling the app I'm using and for comparing 350 entities that already exist in the Graph, its taking roughly 10 seconds.
The text was updated successfully, but these errors were encountered: