Search code examples
c#arraysmongodbmongodb-querymongodb-.net-driver

MongoDB - Select rows by their sequence number in one query


I have an object in the db which contains an array of strings.

{
    "_id": ObjectId("abc123..."),
    "Lines": [
        "string 1",
        "string 2",
        "string 3",
        "...",
        "string 100"
    ]
}

I need to select rows by their sequence number in one query.

For example, I need lines 1, 7, and 15.

var projection = Builders<ContentEntity>.Projection
    .Slice(e => e.Lines2, 1, 1)
    .Slice(e => e.Lines2, 7, 1)
    .Slice(e => e.Lines2, 15, 1);

var entity = await GetContext(categoryId).ContentEntities
    .Find(e => e.Id == contentId)
    .Project<ContentEntity>(projection)
    .FirstOrDefaultAsync(cancellationToken);

return entity;

If I use the slice operator like this, I only get row #15.

I need to select rows by their sequence number in one query from MongoDB with С#.


Solution

  • Think that the last .Slice() overwrite the previous .Slice().

    Pass the query as BsonDocument instead of using the MongoDB Driver Fluent API which is difficult to implement for your scenario.

    Query

    db.collection.find({},
    {
      Lines2: {
        $filter: {
          input: "$Lines",
          cond: {
            $in: [
              {
                $indexOfArray: [
                  "$Lines",
                  "$$this"
                ]
              },
              [
                0,
                6,
                14
              ]
            ]
          }
        }
      }
    })
    

    Demo @ Mongo Playground

    MongoDB .NET Driver syntax

    var projection = new BsonDocument
    {
        {
            "Lines", new BsonDocument
            {
                {
                    "$filter", new BsonDocument
                    {
                        { "input", "$Lines" },
                        {
                            "cond", new BsonDocument
                            {
                                {
                                    "$in", new BsonArray
                                    {
                                        new BsonDocument("$indexOfArray", new BsonArray
                                        {
                                            "$Lines",
                                            "$$this"
                                        }),
                                        new BsonArray { 0, 6, 14 }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    };