【问题标题】:mongodb c# sort by field in a list of entriesmongodb c#按条目列表中的字段排序
【发布时间】:2019-11-26 13:39:41
【问题描述】:

我有一个这样的集合(我删除了与问题无关的字段)

{
   _id:ObjectId('5dd7d946cd9c645f1cdc21ef'),
   Versions: [
      {
           "Barcode" : "200830001128132700636"
      },
       {
           "Barcode" : "200830001128132700637"
      }
   ]
},
{
   _id:ObjectId('5dd7d946cd9c645f1cdc21eg'),
   Versions: [
      {
           "Barcode" : "200830001128132700638"
      },
       {
           "Barcode" : "200830001128132700639"
      }
   ]
}

我需要在整个集合中找到最大(最大)的条形码。

我试过这样的代码:

var options = new FindOptions<Document>
        {
            Limit = 1,
            Sort = Builders<Document>.Sort.Descending(d => d.Versions.Select(v => v.BarCode).Aggregate((v1, v2) => string.Compare(v1, v2) > 0 ? v1 : v2))
        };
using var results = await _context.DocumentiItems.FindAsync(FilterDefinition<Document>.Empty, options);

但我得到 ArgumentNullException,我认为它无法使用聚合来翻译表达式。

你能建议我一个更好的方法吗?如果可能的话,我想避免使用 BSON 字符串并只使用 labmda 表达式。

DocumentiItems的类型是IMongoCollection&lt;Document&gt;

【问题讨论】:

  • 怎么样:_context.DocumentiItems.Max(item=&gt;item.Versions.Max(version=&gt;int32.Parse(version["Barcode"])));
  • sorry IMongoCollection 没有 Max(),如果没有其他解决方案,我会尝试使用 LINQ to mongo 的方法
  • 只使用 AsQueryable :)

标签: c# mongodb .net-core


【解决方案1】:

这可以通过AsQueryable() 接口轻松实现,如下所示:

            var result = collection.AsQueryable()
                           .SelectMany(i => i.Versions)
                           .OrderByDescending(v => v.Barcode)
                           .Take(1)
                           .Single();

这是一个测试程序:

using MongoDB.Entities;
using MongoDB.Entities.Core;
using System;
using System.Linq;

namespace StackOverflow
{
    public class Item : Entity
    {
        public Version[] Versions { get; set; }
    }

    public class Version
    {
        public string Barcode { get; set; }
    }

    public class Program
    {
        private static void Main(string[] args)
        {
            new DB("test", "localhost");

            var result = DB.Queryable<Item>()
                           .SelectMany(i => i.Versions)
                           .OrderByDescending(v => v.Barcode)
                           .Take(1)
                           .Single();

            Console.WriteLine($"max barcode: {result.Barcode}");
            Console.Read();
        }
    }
}

【讨论】:

  • 我不太喜欢 mongo 的 AsQueryable,因为 MongoDriver 通常会以一种有效的方式翻译查询。但是这个解决方案有效,我找不到更好的方法来做到这一点,所以我很高兴接受你的回答。
  • linq 的另一个问题,我可以在不包装到 Task.Run 的情况下异步执行查询吗?
  • @StefanoBalzarotti 是的,只需导入 using MongoDB.Driver.Linq; 并使用 .SingleAsync() 方法
  • 谢谢它,现在可以了。我还有一个问题,查询需要 6 分钟,即使 Barcode 上有索引。集合中有 7500 万份文档,通过条形码查找需要几毫秒。
  • @StefanoBalzarotti 你能确认条形码上有一个降序索引并且它已经完成了所有记录的索引吗?另外,您是否尝试过分析上述查询以检查是否正在使用索引?
猜你喜欢
  • 2011-07-24
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多