2015-05-12 7 views
5

È necessario memorizzare una serie di oggetti Utente all'interno di un nodo Tile. Ogni oggetto Utente contiene tre proprietà primitive; Id (una singola stringa di caratteri alfa), fName e lName. Questo elenco di oggetti è una proprietà del nodo Tile con diverse altre proprietà primitive. L'intero nodo Tile deve essere serializzato su Json, inclusi gli oggetti User nidificati.Memorizzazione dell'oggetto come proprietà in Neo4j

Capisco che Neo non può memorizzare oggetti complessi come proprietà. Ho creato l'utente come nodo separato con id, fName e lName come proprietà, e posso ottenere questi restituiti tramite Cypher. Posso anche ottenere risultati di output JSON per il nodo Tile padre. (In questo caso, gli utenti sono solo una stringa di alfa separati da virgole). Ma come posso ottenere l'output del nodo Utente nidificato all'interno del nodo genitore?

Ho creato un elenco di oggetti Utente (elenco utenti) correlando gli oggetti utente con la stringa di ID utente nel nodo Tile tramite una query Cypher. Ho solo bisogno di ottenere da due uscite JSON separate per un singolo output annidato.

Spero che questo sia abbastanza dettagliato. Sto usando Neo4j 2.1.6 e Neo4jClient. Sto anche usando .Net 4.0.

risposta

4

Si potrebbe fare qualcosa del genere con cypher e fare in modo che il codice restituisca un oggetto composito.

match (t:Tile)-[:CONTAINS_USER]-(u:User) 
where t.name =~ 'Tile.*' 
with {name: t.name, users: collect(u) } as tile 
return collect(tile) as tiles 
+2

Oooh, è imbroglio. Mi piace. :) – FrobberOfBits

+0

Cosa aggiungere a questo per visualizzare i risultati della raccolta? –

+0

ci sono due raccolte: 1) la prima parte della query corrisponde semplicemente alle tessere e crea una collezione di utenti associati. Viene restituito come una mappa composita di tile che contiene alcuni dati di tile e la raccolta di utenti per quella tessera. 2) sta semplicemente prendendo tutte le nuove mappe delle tessere e le restituisce come una raccolta. –

3

Non si deve memorizzare un altro oggetto come proprietà nidificata. Come affermi correttamente, neo4j non supporta questo, ma anche se lo facesse, non dovresti farlo, perché dovresti collegare i due a una relazione. Questo è il punto di forza di un database grafico come neo4j, quindi dovresti giocare a quella forza e usare le relazioni.

Il server ha un formato JSON predefinito che tende a generare nodi come oggetti JSON propri. Ciò significa che praticamente parlando, dal momento che modificherai questo come due nodi separati con una relazione, non puoi ottenere il server di default per nidificare il JSON per un oggetto sotto l'altro. Non anniderà il JSON in questo modo perché non è così che i dati verranno archiviati.

In questo caso, utilizzerei i servizi REST per recuperare il JSON per ciascun oggetto singolarmente, quindi effettuare l'annidamento nel codice: il codice è l'unico posto in cui si saprà quale proprietà deve essere annidato sotto, e come dovrebbe essere fatto.

+0

Sono d'accordo sul fatto che dovresti considerare se memorizzare un oggetto come proprietà nidificata, ma non è corretto dire che non puoi farlo, inoltre penso che sia troppo ampio per dire che non devi memorizzare alcun oggetto come nidificato proprietà. Un esempio è qualcosa di simile a una data, possiamo usare un 'DateTime', ma è anche possibile suddividerlo in 3 nodi connessi di Giorno, Mese e Anno, che potrebbero essere adatti o un enorme overkill. –

+0

Quello che ho finito è serializzare quell'elenco di oggetti utente e metterlo come una stringa nella proprietà utente sul nodo Tile. Richiedere un nodo Tile genera JSON nidificato valido, quindi sono sulla strada giusta, credo. Ho qualche altro bug, quindi è difficile dirlo con certezza se funziona o meno. È accettabile come strategia? Entrambe le tue risposte erano eccellenti, più forti insieme: un bel lavoro di squadra! –

+0

@ChrisSkardon punto preso; ovviamente con qualsiasi tecnologia c'è pochissimo che fondamentalmente non puoi fare. E prendo quello che intendi per DateTime, ma questo è un caso speciale, di solito pensato come un tipo primitivo incorporato e non un tipo complesso definito dall'utente. Stavo pensando a domini complessi/tipi definiti dall'utente come "Conto bancario". *Potresti farlo? Beh sì ... certo, ma è difficile immaginare scenari * comuni * in cui quella sarebbe la decisione migliore. (Naturalmente puoi anche trovare delle nicchie insolite dove potrebbe essere preferibile) – FrobberOfBits

2

In aggiunta a queste risposte, si noti che, se non è necessario coinvolgere le proprietà di sottocampo a tutte le vostre domande (ad esempio, la ricerca di piastrelle in cui un'User.name è "X"), si può semplicemente serializza i campi degli oggetti su una stringa prima dell'inserimento (ad es. Con JSON.stringify) e li unserializza durante la lettura dal DB.

Ciò è particolarmente utile quando si desidera "allegare" dati strutturati a un nodo, ma non si cura molto di questi dati per quanto riguarda le relazioni nel DB (ad esempio le preferenze dell'utente).