How to create MongoDB MultiKey index on attribute of items in an array .NET Driver

旧巷老猫 提交于 2019-12-12 09:33:50

问题


I have a MongoDB collection "foos" containing items which each have an array of "bars". That is, "foo" has the following schema:

{
    "id": UUID
    "name": string
    ...
    "bars": [
        "id": UUID
        "key": string
        ...
    ]
}

I need to create an index on name and bar.key using the MongoDB C# .NET Mongo driver.

I presumed I could use a Linq Select function to do this as follows:

Indexes.Add(Context.Collection<FooDocument>().Indexes.CreateOne(
    Builders<FooDocument>.IndexKeys
        .Descending(x => x.Bars.Select(y => y.Key))));

However this results in an InvalidOperationException:

System.InvalidOperationException: 'Unable to determine the serialization information for x => x.Bars.Select(y => y.Id).'

The Mongo documentation on MultiKey indexes shows how to create such an index using simple dot notation, i.e.

db.foos.createIndex( { "name": 1, "bars.key": 1 } )

However the MongoDB driver documentation seems to suggest that using a Linq function as I'm doing is correct.

How can I create a multikey index on my collection using the MongoDB .NET Driver, preferably using a Linq function?


回答1:


This is an example how to do it with C#

var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2));

await collection.Indexes.CreateOneAsync(indexDefinition); 

UPDATE

Regarding index within the array, closest what i was able to find is to use "-1" as index whene you building your index key. As i understand from github source code is is a valid option in case of building queries.

var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2[-1].Key));

await collection.Indexes.CreateOneAsync(indexDefinition); 

"-1" is a hardcoded constant in side mongodb C# drivers which means "$" (proof). So this code would try to create index:

{ "Key1": 1, "Key2.$.Key": 1 }

which is fine for querying info from database, but not allowed (will throw an exception "Index key contains an illegal field name: field name starts with '$'") to use in indexes. So i assume it should be changed in mongodb drivers to make it work. Something like "-2" means empty operator. In that case we could use

var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2[-2].Key));

await collection.Indexes.CreateOneAsync(indexDefinition); 

which would generate index like:

{ "Key1": 1, "Key2.Key": 1 }

So basically i don't think it is possible right now to build index you want with pure Linq without changing mongo C# drivers.

So i think your only option do like this, still C# but without Linq

await collection.Indexes.CreateOneAsync(new BsonDocument {{"name", 1}, {"bars.key", 1}});



回答2:


This appears to be a requested feature for the C# driver, although it hasn't seen any progress lately. That said, someone did submit a rough-and-ready solution there on the JIRA thread, so perhaps that will do the job for you.




回答3:


You can create a string index and use nameof() in C# 6:

Indexes.Add(Context.Collection<FooDocument>().Indexes.CreateOne($"{nameof(FooDocument.Bars)}.{nameof(Bars.Key)}"));



回答4:


As of "MongoDB.Driver" Version="2.8.0" syntax has been changed and some of the methods has been deprecated.Following is the way to achieve the same . Please note the CreateOneAsync(new CreateIndexModel<FooDocument>(indexDefinition)); part

var indexDefinition = Builders<FooDocument>.IndexKeys.Combine(
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key1),
    Builders<FooDocument>.IndexKeys.Ascending(f => f.Key2[-1].Key));


  await collection.Indexes.CreateOneAsync(new CreateIndexModel<FooDocument>(indexDefinition)); 


来源:https://stackoverflow.com/questions/44070496/how-to-create-mongodb-multikey-index-on-attribute-of-items-in-an-array-net-driv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!