MongoDB使用2个(或更多)字段进行查找。

huangapple go评论98阅读模式
英文:

MongoDB lookup using 2 (or more) fields

问题

我正在尝试通过两个字段查找两个Mongo集合。
我尝试创建一个本地键和外键的对象/匿名对象。

List<JoinedData> requests = await _persons
    .Aggregate()
    .Lookup<Person, Activity, JoinedData>(activities,
        x => new { Id = x.EntityId, Type = x.EntityType },
        x => new { Id = x.PersonId, Type = "Person" },
        @as: x => x.activities
    )

但是我遇到了一个错误:

MongoDB.Driver.Linq.ExpressionNotSupportedException : 不支持的表达式:new <><>f__AnonymousType0`2(Id = x.EntityId, Type = x.EntityType)。

是否有一种方法可以像这样进行查找?

谢谢!

英文:

I'm trying to lookup 2 mongo collection by 2 fields
I've tried creating an object / anonymous object as the local and foreign keys.

List&lt;JoinedData&gt; requests = await _persons
    .Aggregate()
    .Lookup&lt;Person, Activity, JoinedData&gt;(activities,
        x =&gt; new { Id = x.EntityId, Type = x.EntityType },
        x =&gt; new { Id = x.PersonId, Type = &quot;Person&quot; },
        @as: x =&gt; x.activities
    )

but I get an error:

MongoDB.Driver.Linq.ExpressionNotSupportedException : Expression not supported: new &lt;&gt;f__AnonymousType0`2(Id = x.EntityId, Type = x.EntityType).

is there a way to lookup like this?

thanks!

答案1

得分: 0

根据文档,我不确定即使在你使用的查询中,本地键和外部键在理论上是否可以是多字段的。尝试查看具有let参数的这个查找表单

我怀疑这可能不会有帮助,但尝试使用常规类而不是动态类。

你看到的错误只是说驱动程序无法正确处理提供的表达式,查询本身是否有效以及是否可以由服务器处理是不同的问题。鉴于我上面提到的第1点,我怀疑这可能不会有帮助,但你可以尝试使用基于原始字符串的配置,这将完全排除解析表达式,并且你可以期望将此查询发送到服务器(再次强调,此查询可能会被服务器拒绝,但你可以尝试):

List<JoinedData> requests = await _persons
    .Aggregate()
    .Lookup<Person, Activity, JoinedData>(activities,
        "#local option definition#",
        "#foreign option definition#",
        "#as option definition#"
    )

其中##之间的值应该是原始MQL形式的查找参数,因此你可以将其视为MQL查询的占位符,例如在Mongo shell中使用:

db._persons.aggregate( [
   {
      $lookup:
         {
           from: "activities",
           localField: "#local option definition#",
           foreignField: "#foreign option definition#",
           as: "#as option definition#"
         }
  }] )

我建议打开Mongo shell并在那里构建(并验证结果)你正在寻找的查询。然后只需将此查询复制到C#驱动程序中(如果它有效,则以表达式形式或使用原始方法)。

注意,基于原始字符串的参数不会在客户端更改,因此你应该使用与你的数据库结构中的字段名称相同的字段名称(例如_id而不是Id)。

英文:

Writing it as answer since it's quite big. Some of the below can require more investigations:

  1. Based on the documentation, I'm not sure whether local and foreign keys can be multi fields even in theory in query you use. Try looking at this lookup form with let argument.

  2. I doubt it will help, but try using regular classes instead dynamic.

  3. The error you see says only that the driver can't correctly handle provided expression, whether the query itself is valid or whether it can or can't be handled by server is a different question. Given the #1 I wrote above I doubt it will help, but you can try using a raw string-based configuration that will exclude parsing expressions at all and you can expect that exactly this query will be send to the server (again this query may be rejected by server, but you can try):

    List&lt;JoinedData&gt; requests = await _persons
      .Aggregate()
      .Lookup&lt;Person, Activity, JoinedData&gt;(activities,
          &quot;#local option definition#&quot;,
          &quot;#foreign option definition#&quot;,
          &quot;#as option definition#&quot;
       )
    

where values between # and # should be a lookup arguments in a raw MQL form, so think about it as placeholders for the MQL query that you can use for example in the mongo shell:

   db._persons.aggregate( [
   {
      $lookup:
         {
           from: &quot;activities&quot;,
           localField: &quot;#local option definition#&quot;,
           foreignField: &quot;#foreign option definition#&quot;,
           as: &quot;#as option definition#&quot;
         }
  }] )

I would recommend opening mongo shell and build (and validate results) a query you're looking for there. Then just copy this query to the c# driver (in expression form if it works or with raw approach).

pay attention that raw string-based arguments won't be changed on the client side, so you should use field names as in your db structure (for example _id instead Id).

huangapple
  • 本文由 发表于 2023年7月13日 23:23:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定