如何在 MongoDB 中组合 3 个查询的结果?

Posted

技术标签:

【中文标题】如何在 MongoDB 中组合 3 个查询的结果?【英文标题】:How can I combine the results of 3 queries in MongoDB? 【发布时间】:2020-10-12 21:54:54 【问题描述】:

我制作了以下过滤器,希望将所有 3 个 $and 数组的结果组合在一起,但它只匹配其中一个块。

如果满足条件,我如何组合每个 $and 数组返回的结果。希望这很清楚。 $and 数组我不知道该怎么称呼。

const filter = 
      $or: [
        
          $and: [
             category: req.query.category ,
             tags: req.query.subCategory ,
            contentType: req.query.contentType,
            req.query.searchTerm !== ""
              ? 
                  name: 
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  ,
                
              : ,
          ],
          $and: [
              category: req.query.category ,
             tags: req.query.subCategory ,
            contentType: req.query.contentType,
            req.query.searchTerm !== ""
              ? 
                  description: 
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  ,
                
              : ,
          ],
          $and: [
              category: req.query.category ,
             tags: req.query.subCategory ,
            contentType: req.query.contentType,
            req.query.searchTerm !== ""
              ? 
                  tags: 
                    $regex: "(?i)" + req.query.searchTerm + "(?-i)",
                    $options: "i",
                  ,
                
              : ,
          ],
        ,
      ],
    ;
 await Content.paginate(filter, options, (err, result) => 
      if (err) 
        res.status(500).send(err);
       else 
        res.json(result);
      
    );

编辑:下面是可以在数据库中找到的两个条目的示例。它应该工作的方式是它应该使用categorysubCategorycontentType过滤掉数据库中的条目,这样我现在只有具有相同categorysubCategory的条目, 和contentType 中指定的req.query,我将其称为firstFilterResult。从那里,我试图在firstFilterResult 中搜索,看看我是否有与nametagdescription 匹配的条目。所以基本上catgeorysubCategorycontentType 只是用来缩小结果范围,以便我可以找到nametagdescription 的匹配项。我上面的代码并没有完全做到这一点,但这是它背后的想法,我认为我会做类似的事情,但我想我错了。

contents: [
      
        tags: [
          'food',
          'drinks',
          'card',
          'account'
        ],
        _id: '1d13ff7m6db4d5417cd608f4',
        name: 'THE NAME FOR THIS PIECE OF CONTENT',
        description: 'In here I will begin to talk about...',
        content_id: '5dbcb998ad4144390c244093',
        contentType: 'quiz',
        date: '2019-06-03T04:00:00.000Z',
        category: 'food',
        image: 'https://IMAGE.PNG',
        __v: 0
      ,
      
        tags: [
          'computer',
          'laptop'
        ],
        _id: '7d1b940b1c9d44000025db8c',
        name: 'THE NAME FOR THIS PIECE OF CONTENT',
        description: 'This is another description',
        content_id: '5f1b963d1c9d44000055db8d',
        contentType: 'tool',
        date: '2019-06-03T04:00:00.000Z',
        category: 'money',
        image: 'https://IMAGE.PNG',
        __v: 0
      
 ]

【问题讨论】:

$or: [ $and: expr, $and: expr, ... ] 应该做你想做的事。也许如果您发布 3 或 4 个代表性文档,我们可以看到问题。另外:$and exprs 看起来一样...? 每个$and` expression. tags: $regex: "(?i)" + req.query.searchTerm + "(?-i)", $options: "i", ,都不同,这个有'tag',而其他有'description'和'name' 而无效的证明是,如果我删除 2 个 and 表达式,那么我会得到不同的结果。例如,如果我只有一个具有“标签”的查询,那么我会得到该查询的正确结果,但随后我添加了描述,我丢失了那些原始结果,它们被替换为描述中返回的任何内容 我编辑了这个例子,希望这更有意义? 尝试在构造 filter 之后记录它的值,以确保它看起来确实符合您的预期。 【参考方案1】:

我终于可以使用它了

 const catFilter =
      req.query.category !== "" ?  category: req.query.category  : ;
    const subCatFilter =
      req.query.subCategory !== "" ?  tags: req.query.subCategory  : ;
    const typeFilter =
      req.query.contentType !== ""
        ?  contentType: req.query.contentType 
        : ;
    const filter = 
      $and: [
        
          $or: [
            
              name: 
                $regex: req.query.searchTerm,
                $options: "i",
              ,
            ,
            
              description: 
                $regex: req.query.searchTerm,
                $options: "i",
              ,
            ,
            
              tags: 
                $regex: req.query.searchTerm,
                $options: "i",
              ,
            ,
          ],
        ,
        catFilter,
        subCatFilter,
        typeFilter,
      ],
    ;

【讨论】:

【参考方案2】:

由于$or 的每个元素都包含相同的 3 个检查,但其中一个检查是不同的,因此可以将这些检查分开,并且只有在指定搜索词时才需要 $or

传递options:"i" 使整个正则表达式匹配不区分大小写,因此不必用(?i)(?-i) 包围搜索字符串

以下内容应构建您正在尝试的过滤器,而不使用空对象:

// base query that checks the common fields
var filter = 
               category: req.query.category,
               tags: req.query.subCategory,
               contentType: req.query.contentType
;

// if a search term is provided, add in the additional critera
if (req.query.searchTerm !== "") 
  var regex = 
               $regex: req.query.searchTerm, 
               options:"i"
  ;
  filter['$or'] = [
        name: regex ,
        description: regex ,
        tags: regex 
  ]

如果这没有得到您想要的结果,请编辑问题并添加一些示例文档,以便我们看到问题。

【讨论】:

不幸的是,这不起作用:/如果我将其插入,则搜索结果中不会返回任何内容。我添加了其他内容,感谢您的帮助!

以上是关于如何在 MongoDB 中组合 3 个查询的结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MongoDB 查询中编写 3 个条件? [关闭]

如何编写猫鼬查询来组合来自两个模型的数据?

详细教程一文参透MongoDB聚合查询

限制 MongoDB 中的查询结果

MongoDB 聚合管道(Aggregation Pipeline)

mongoDB表与表的关系及聚合管道查询