Extracting information from 2 documents using mongodb driver - mongodb

I have three different collections.
The first collection is User, (userId, name, address.. etc)
the second collection is service, (serviceId, name, title)
the third collection is service2User(serviceId, and recipientUserId)
(I know i could use some array inside the service instead of the service2User
this is done because the serviceRegister2User contain much more then 2 fields, and can be very big.)
I need to find a collection of users which don't have current service (i.e service=10)
(the solution can be done by: linq or directly through the c# mongo driver)
to my best understand this is a two process action
First: I need to search the serviceRegister2User collection and find all recipientUserId which have already serviceId=10.
Second: I need to find all users which are different from the users found in my first query.
those users are users which did not register to serviceId=10
The collection found after the second process is the wanted result.
Can someone tell me how to do it in both way?
- linq or directly through the c# mongo driver
if it is done by Linq driver, then it need to return MongoCollection.
Thank you.

Related

"Join" multiple Algolia indices?

Is it possible to "join" indices in Algolia to get a merged result?
For example:
If I have two indices : one for 'users', and one for 'events'. Users each have id and name attributes. Events each have date and userId attributes.
How would I go about searching for all users named "bob", and for each user also return the next 5 events associated with them?
Is it possible to "join" them like you would in a relational database? Or do I need to search for users, then iterate through the hits, searching for events for each user? What's the best solution for this type of query here?
Algolia is not designed as a relational database. To get to what you're trying to achieve, you have to transform all your records into "flat" objects (meaning, each object also includes all their linked dependencies).
In your case, what I would do is to add a new key to your user records, named events and have it be an array of events (just like you save them in the events table). This way, you got all the information needed in one call.
Hope that helps,

Is it possible to group multiple collections in mongodb

so I'm working with a database that has multiple collections and some of the data overlaps in the collection . In particular I have a collection called app-launches which contains a field called userId and one called users where the _id of a particular object is actually the same as the userId in app-launches. Is it possible to group the two collections together so I can analyze the data? Or maybe match the the userId in app-launches with the _id in users?
There is no definit answer for your question Jeffrey and none of the experts here can tell you to choose which technique over other just by having this information.
After going through various web pages over internet and mongo documentation and understanding the design patterns used in Mongo over a period of time, How I would design it depends on few things which I can try explaining it here in short.
if you have a One-To-One relation then always prefer to choose Embedding over Linking. e.g. User and its address (assuming user has only one address) thus you can utilize the atomicity (without worrying about transactions) as well easily fetch the records without too and fro to bring other information as in the case of Linking (like in DBRef)
If you have One-To-Many relation then you need to consider whether you can do the stuff by using Embedding (prefer this as explained the benefits in point 1). However, embedding would help you if you always want the information altogether e.g. Post/Comments where your requirement is to get the post and all of its comments by postId let say. But think of a situation where you need to get all the comments (and it related posts) which contains some specific tags in comments. in this case you should prefer Linking Because if you go via Embedding route then you would end up getting all the collection of comments for a post and you have to filter the desired comments.
for a Many-To-Many relations I would prefer two separate entities as well another collection for linking them e.g. Product-Category.
-$

Retrieve records in mongoDB using bidirectional query

I have two collections - Tickets and Users. Where a user can have one to many tickets. The ticket collection is defined as follows
Ticket = {_id, ownerId, profile: {name}}
The ownerId is used to find all tickets that belong to a specific person. I need to write a query that gets me all users with no tickets.
How can i write this query without having to loop through all users, checking if the userID shows up in any Tickets?
Would a bidirectional storage cause me any performance problems ? For example, if i were to change my users collection and add an array of tickets: [ticketID, ticketID2, ...]?
I'd go with the array of tickets being stored in users. As far as I know, Mongo doesn't really have a way to query one collection based on the (lack of) elements in another collection. With the array, though, you can simply do db.users.find({tickets:[]}).

Querying Raven Db

I have an instance of Raven Db at localhost:8081. I made sure to change raven's config file to allow anonymous access. I created a database named AT. Inside AT I have a collection named Admins. Inside of Admins I have two documents. I'm trying to retrieve some data via Rest using RestClient. I try to hit the db using:
http://localhost:8081/docs/admins/7cb95e9a (last bit is the id of the document I want).
and
http://localhost:8081/docs/at/admins/7cb95e9a.
With both I receive a 404. I'm not sure what I'm missing here. Can someone point me in the right direction?
The URL has the following format:
http://localhost:8081/databases/{{database-name}}/docs/{{document-id}}.
Collection is a virtual thing. get a document only by its ID, there no nothing on collection here. The document ID can be anything you set, but if you let RavenDB to generate it, it will probably be admins/1.

How to get list of aggregates using JOliviers's CommonDomain and EventStore?

The repository in the CommonDomain only exposes the "GetById()". So what to do if my Handler needs a list of Customers for example?
On face value of your question, if you needed to perform operations on multiple aggregates, you would just provide the ID's of each aggregate in your command (which the client would obtain from the query side), then you get each aggregate from the repository.
However, looking at one of your comments in response to another answer I see what you are actually referring to is set based validation.
This very question has raised quite a lot debate about how to do this, and Greg Young has written an blog post on it.
The classic question is 'how do I check that the username hasn't already been used when processing my 'CreateUserCommand'. I believe the suggested approach is to assume that the client has already done this check by asking the query side before issuing the command. When the user aggregate is created the UserCreatedEvent will be raised and handled by the query side. Here, the insert query will fail (either because of a check or unique constraint in the DB), and a compensating command would be issued, which would delete the newly created aggregate and perhaps email the user telling them the username is already taken.
The main point is, you assume that the client has done the check. I know this is approach is difficult to grasp at first - but it's the nature of eventual consistency.
Also you might want to read this other question which is similar, and contains some wise words from Udi Dahan.
In the classic event sourcing model, queries like get all customers would be carried out by a separate query handler which listens to all events in the domain and builds a query model to satisfy the relevant questions.
If you need to query customers by last name, for instance, you could listen to all customer created and customer name change events and just update one table of last-name to customer-id pairs. You could hold other information relevant to the UI that is showing the data, or you could simply hold IDs and go to the repository for the relevant customers in order to work further with them.
You don't need list of customers in your handler. Each aggregate MUST be processed in its own transaction. If you want to show this list to user - just build appropriate view.
Your command needs to contain the id of the aggregate root it should operate on.
This id will be looked up by the client sending the command using a view in your readmodel. This view will be populated with data from the events that your AR emits.