I am working on a rather large MongoDB database and am wondering if there is a more effective way to some queries. For example, I store lots of instances of Game
in the db, where the Game
class looks as follows:
public class Game{
[BsonId]
public long ID { get; set; }
// ... some more properties
public List<Player> Players { get; set; }
}
where each game instance has a list of Player
, which in turn has some properties, like Name
.
In one view model I want to bind a ComboBox
to the name of all players in the database - but recall that the same player might have played many games. I load them as follows:
private void LoadPlayersNames() {
var _l = StaticMongo.GetGames.SelectMany(n => n.Players).Select(n => n.Name);
PlayerNames = new ObservableCollection<string>(new HashSet<string>(_l));
}
And in the static class StaticMongo
I have a static instance of the MongoClient
and the IMongoDatabase
, And I expose the GetGames
property in StaticMongo
as follows,
private readonly static IMongoDatabase _database;
public static IMongoQueryable<DetailedHand> GetGames {
get {
return _database.GetCollection<Game>("Games").AsQueryable();
}
}
So to make this more conrete, following questions:
1: Is the way I get the unique player names (via HashSet
) a good way or is there a better way to query for unique names in this context. 2: Does the static MongoDB instance, together with exposing the database collections AsQueryable have drawbacks?
I know the formulaion might be a bit opinion-based, yet I hope to get some alternative ways to do queries of this kind as this does not look to be the ideal way to me.
I feel you should use aggregation framework for finding unique names which is faster:
Pure mongo query would be:
db.games.aggregate(
{
"$unwind": "$players"
},
{
"$group": {
"_id": "$players.name",
}
}
)
You can see MongoDB Aggregation Framework Examples in C# for converting my db query to C# usage.
Update:
Learning aggregation in C# for you. Believe me or not. But aggregation is faster than AsQueryable()
var collection = _database.GetCollection<BsonDocument>("games");
var pipeline = collection.Aggregate()
.Unwind(i => i.players)
.Group(new BsonDocument { { "_id", "$players.name" } });
Check if it is working.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.