如何在MongoDB中查询有序数组子集及开头匹配的数组?
MongoDB有序数组匹配的两种查询实现
测试数据
{ "_id" : 1, "array" : [ "a", "b", "c" ] } { "_id" : 2, "array" : [ "a", "b", "c" ] } { "_id" : 3, "array" : [ "x", "a", "b", "c" ] } { "_id" : 4, "array" : [ "x", "b", "c", "a" ] }
一、匹配以指定有序子数组开头的文档
需求:筛选array字段严格以["a", "b"]按顺序开头的文档(预期结果:_id 1、2)
实现方式:通过$expr结合$slice和$eq,截取数组前N个元素(N为目标子数组长度)与目标数组直接对比:
db.collection.find({ $expr: { $eq: [ { $slice: ["$array", 2] }, // 提取array字段的前2个元素 ["a", "b"] // 目标开头子数组 ] } })
说明:$slice会截取数组的前2个元素,只有截取结果与["a","b"]完全一致时,文档才会被匹配。_id 3的前两个元素是["x","a"],_id 4是["x","b"],均不满足条件,因此被排除。
二、匹配包含指定有序子数组的文档
需求:筛选array字段中存在按顺序排列的["a", "b"]的文档(预期结果:_id 1、2、3)
实现方式:利用$expr结合$indexOfArray判断元素位置关系,确保"a"在"b"之前出现,同时保证两个元素都存在于数组中:
db.collection.find({ $expr: { $and: [ { $ne: [{ $indexOfArray: ["$array", "a"] }, -1] }, // 确保数组包含"a" { $ne: [{ $indexOfArray: ["$array", "b"] }, -1] }, // 确保数组包含"b" { $lt: [{ $indexOfArray: ["$array", "a"] }, { $indexOfArray: ["$array", "b"] }] } // 确保"a"在"b"之前出现 ] } })
说明:$indexOfArray返回元素在数组中的索引,元素不存在时返回-1。通过判断a的索引小于b的索引,保证两者按顺序出现。_id 4中a的索引是3,b的索引是1,不满足$lt条件,因此被排除。
内容的提问来源于stack exchange,提问作者thenubus
相关产品推荐
相关产品推荐

