programing

배열 크기가 1보다 큰 문서에 대한 쿼리

lastcode 2023. 2. 13. 20:34
반응형

배열 크기가 1보다 큰 문서에 대한 쿼리

다음 형식의 문서를 포함한 MongoDB 컬렉션이 있습니다.

{
  "_id" : ObjectId("4e8ae86d08101908e1000001"),
  "name" : ["Name"],
  "zipcode" : ["2223"]
}
{
  "_id" : ObjectId("4e8ae86d08101908e1000002"),
  "name" : ["Another ", "Name"],
  "zipcode" : ["2224"]
}

현재 특정 어레이 크기와 일치하는 문서를 가져올 수 있습니다.

db.accommodations.find({ name : { $size : 2 }})

그러면 2개의 요소가 있는 문서가 올바르게 반환됩니다.name어레이는 할 수 없습니다.$gt명령어를 사용하여 모든 문서를 반환합니다.name필드의 배열 크기가 2를 초과합니다.

db.accommodations.find({ name : { $size: { $gt : 1 } }})

다음을 포함하는 모든 문서를 선택하려면 어떻게 해야 합니까?name크기가 1보다 큰 어레이(현재 데이터 구조를 변경할 필요 없이 가능한 경우)

MongoDB 2.2+에서는 쿼리 오브젝트 키에서 숫자 배열 인덱스(0 기반)를 사용할 수 있으므로 이를 보다 효율적으로 수행할 수 있습니다.

// Find all docs that have at least two name array elements.
db.accommodations.find({'name.1': {$exists: true}})

부분 필터 식을 사용하는 인덱스를 사용하여 이 쿼리를 지원할 수 있습니다(3.2+ 필요).

// index for at least two name array elements
db.accommodations.createIndex(
    {'name.1': 1},
    {partialFilterExpression: {'name.1': {$exists: true}}}
);

업데이트:

mongodb 버전 2.2 이상의 경우 @Johnny에서 설명한 보다 효율적인 방법HK는 또 다른 대답입니다.


  1. $where 사용

    db.docations.find({ $where: "this.name.length > 1" } );

그렇지만.....

Javascript는 이 페이지에 나열된 네이티브 연산자보다 실행 속도가 느리지만 매우 유연합니다.상세한 것에 대하여는, 서버측의 처리 페이지를 참조해 주세요.

  1. 추가 필드 생성NamesArrayLengthnames 배열 길이로 업데이트한 후 쿼리에서 사용합니다.

    db.accommodations.find("NamesArrayLength": {$gt: 1) ;

더 나은 솔루션이 될 것이며 훨씬 더 빠르게 동작할 것입니다(이것에 대해 인덱스를 작성할 수 있습니다.

이것이 당신의 질문에 가장 빨리 대답할 수 있는 질문이라고 생각합니다. 왜냐하면 그것은 통역된 것을 사용하지 않기 때문입니다.$where절:

{$nor: [
    {name: {$exists: false}},
    {name: {$size: 0}},
    {name: {$size: 1}}
]}

즉, "이름(존재하지 않거나 빈 배열)이 없거나 하나의 이름만 있는 문서를 제외한 모든 문서"를 의미합니다.

테스트:

> db.test.save({})
> db.test.save({name: []})
> db.test.save({name: ['George']})
> db.test.save({name: ['George', 'Raymond']})
> db.test.save({name: ['George', 'Raymond', 'Richard']})
> db.test.save({name: ['George', 'Raymond', 'Richard', 'Martin']})
> db.test.find({$nor: [{name: {$exists: false}}, {name: {$size: 0}}, {name: {$size: 1}}]})
{ "_id" : ObjectId("511907e3fb13145a3d2e225b"), "name" : [ "George", "Raymond" ] }
{ "_id" : ObjectId("511907e3fb13145a3d2e225c"), "name" : [ "George", "Raymond", "Richard" ] }
{ "_id" : ObjectId("511907e3fb13145a3d2e225d"), "name" : [ "George", "Raymond", "Richard", "Martin" ] }
>

Aggregate도 사용할 수 있습니다.

db.accommodations.aggregate(
[
     {$project: {_id:1, name:1, zipcode:1, 
                 size_of_name: {$size: "$name"}
                }
     },
     {$match: {"size_of_name": {$gt: 1}}}
])

// "size_of_name"을 전송 문서에 추가하여 이름 크기를 필터링합니다.

$expr(3.6 mongo 버전 연산자)을 사용하여 일반 쿼리에서 집약 함수를 사용할 수 있습니다.

와 비교합니다.

db.accommodations.find({$expr:{$gt:[{$size:"$name"}, 1]}})

다음과 같은 작업을 수행해 보십시오.

db.getCollection('collectionName').find({'ArrayName.1': {$exists: true}})

1은 숫자입니다.50보다 큰 레코드를 가져오려면 ArrayName.50 감사합니다.

MongoDB 3.6에는 $expr https://docs.mongodb.com/manual/reference/operator/query/expr/이 포함되어 있습니다.

$expr을 사용하여 $match 내의 식을 평가하거나 찾을 수 있습니다.

{ $match: {
           $expr: {$gt: [{$size: "$yourArrayField"}, 0]}
         }
}

또는 검색

collection.find({$expr: {$gte: [{$size: "$yourArrayField"}, 0]}});

위 중 어느 것도 나에게 통하지 않았다.이건 해냈으니까 공유할게요.

db.collection.find( {arrayName : {$exists:true}, $where:'this.arrayName.length>1'} )
db.accommodations.find({"name":{"$exists":true, "$ne":[], "$not":{"$size":1}}})

위의 답변은 모두 유효합니다만, 처음에 시도한 것은 올바른 방법이지만, 구문이 거꾸로 되어 있을 뿐입니다(스위치 「$size」와 「$gt」).

정답:

db.collection.find({items: {$gt: {$size: 1}}})

배열 필드가 특정 길이보다 긴 항목을 찾기 위해 이 솔루션을 찾았습니다.

db.allusers.aggregate([
  {$match:{username:{$exists:true}}},
  {$project: { count: { $size:"$locations.lat" }}},
  {$match:{count:{$gt:20}}}
])

첫 번째 $match 집계는 모든 문서에 대해 true 인수를 사용합니다.공백일 경우, 나는

"errmsg" : "exception: The argument to $size must be an Array, but was of type: EOO"

MongoDB 집약을 통해 다음 작업을 수행할 수 있습니다.

db.collection.aggregate([
  {
    $addFields: {
      arrayLength: {$size: '$array'}
    },
  },
  {
    $match: {
      arrayLength: {$gt: 1}
    },
  },
])

이것은 나침반에서도 동작합니다.인덱싱 없이 시도한 것 중 가장 빠릅니다.

 {$expr: {
            $gt: [
              {
                $size: { "$ifNull": [ "$name", [] ] }
              },
              1
            ]
          }}

$expr을 사용하여 커버할 수 있습니다.

// $expr: Allows the use of aggregation expressions within the query language.
// syntax: {$expr: {<expression>}}

db.getCollection("person_service").find(
    { 
        "$expr" : { 
            // services is Array, find services length gt 3
            "$gt" : [
                { 
                    "$size" : "$services"
                }, 
                3.0
            ]
        }
    }
)

언급URL : https://stackoverflow.com/questions/7811163/query-for-documents-where-array-size-is-greater-than-1

반응형