【问题标题】:Filter by String Embedded Documents from the main document using MongoEngine - Python Flask使用 MongoEngine - Python Flask 从主文档中按字符串嵌入文档过滤
【发布时间】:2020-06-01 18:17:21
【问题描述】:

我正在尝试按字符串(LIKE Query SQL 等效项)从父文档中过滤嵌入文档。

这是我现在拥有的:

def resolve_friend(root, info, **kwargs):
    phone = kwargs.get('phone', None)
    search_string = kwargs.get('searchString', None)
    try:
        // I am retrieving the parent doucment by phone number first
        account = AccountModel.objects(phone=phone).first()

        if account is None:
            return ResponseMessageField(is_success=False, message="User does not exists.")

        top_friends = None

        // Now I want to filter the Friends field from the account by the search string.
        // In the friends' field, there are multiple documents.  The idea is to get the friends
        // matching the string from their first_name / last_name 

        if search_string:
            regex = re.compile('.*' + search_string + '.*', re.IGNORECASE)

            //doesn't work any of these below
            # top_friends = account.friends.filter((Q(first_name='test') | Q(last_name='test'))) 
            top_friends = AccountModel.objects(friends__first_name__icontains='tes').all() 


        all_friends = account.friends.filter(request_status="ACCEPTED")   //this works fine
        return retrieve_friend_list_graphql(top_friends=top_friends, all_friends=all_friends)
    except Exception as e:
        return ResponseMessageField(is_success=False, message="Account fetch error. " + str(e))

这些行不起作用

top_friends = account.friends.filter((Q(first_name='test') | Q(last_name='test'))) 
top_friends = AccountModel.objects(friends__first_name__icontains='tes').all() 

我无法在 mongoengine 中使用搜索字符串过滤 account.friends.filter()

这是带有 friends 字段的完整 account 文档。

{
  "_id": {
    "$oid": "5e3485c2dd26ea191faf2861"
  },
  "identity": "0b1170fc50979464c352c34c2e9fd7aa",
  "username": "Shuvro",
  "first_name": "",
  "middle_name": "",
  "last_name": "",
  "phone": "+8801521483999",
  "is_active": false,
  "is_activation_sent": true,
  "activation_code": "9815",
  "is_phone_confirmed": false,
  "is_email_active": false,
  "is_email_activation_sent": true,
  "email_activation_code": "7529c11c2b0eb55314fb01355d5cc78f",
  "is_email_confirmed": false,
  "friends": [
    {
      "identity": "bb30337b7fbcc5080b9fe3a2b6a60383",
      "username": "Shuvro",
      "first_name": "lord",
      "middle_name": "",
      "last_name": "",
      "email": "shuvro@test.com",
      "phone": "+8801521483720",
      "request_status": "PENDING",
      "request_type": "RECEIVED",
      "request_created_at": {
        "$date": {
          "$numberLong": "1580676652938"
        }
      }
    },
    {
      "identity": "06df8a2dd85c3ebc5b49817333f2aeff",
      "username": "",
      "first_name": "test",
      "middle_name": "",
      "last_name": "test last",
      "phone": "+8801521474747",
      "request_status": "PENDING",
      "request_type": "RECEIVED",
      "request_created_at": {
        "$date": {
          "$numberLong": "1581876704806"
        }
      }
    }
  ]
}

请帮忙,我怎样才能从父文档中按他们的名字过滤掉朋友。 谢谢。

【问题讨论】:

    标签: python mongodb flask mongoengine


    【解决方案1】:

    您可以尝试使用 mongodb 正则表达式运算符使用__raw__ 查询,例如:

    AccountModel.objects(__raw__={"friends": { "$elemMatch": { "first_name": { "$regex": ".*test.*" } } } })
    

    显然,如果您想将结果限制为只有一个用户,您应该将帐户 ID 一起传递。

    AccountModel.objects(__raw__={"friends": { "$elemMatch": { "first_name": { "$regex": ".*test.*" } } }, "_id" : account.id })
    

    希望它适合你。

    【讨论】:

    • 感谢@Kenny 的回复。但这不起作用。由于我已经在 account 中拥有该文档,因此我只需要在 Friends 字段中过滤结果。
    • @Shuvro 我的错......现在我看到它是一个嵌入文档,我已经更新了我的答案,请检查它现在是否有效。刚刚在我的代码上测试了类似的上下文。
    • 返回父文档本身。但我需要获取匹配的嵌入文档。
    • @Shuvro 我明白你现在的意思了......这是一个很难的问题,下面的答案可能会给你一些启示:stackoverflow.com/a/15680567/8969084
    猜你喜欢
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多