복붙노트

[MONGODB] MongoDB의 여러 컬렉션에서 검색

MONGODB

MongoDB의 여러 컬렉션에서 검색

나는 MongoDB를 이론 및 지원 조인, 나는 가능한 한만큼 임베디드 문서 또는 비정규 화를 사용해야하지만, 여기에 간다하지 않는 것입니다 사실을 알고 :

나는 다음과 같은 여러 문서를 가지고 :

예:

Users:
{ _id: 1, first_name: 'Bill', last_name: 'Gates', suburb: 1 }
{ _id: 2, first_name: 'Steve', last_name: 'Jobs', suburb: 3 }

Suburb:
{ _id: 1, name: 'Suburb A', state: 1 }
{ _id: 2, name: 'Suburb B', state: 1 }
{ _id: 3, name: 'Suburb C', state: 3 }

State:
{ _id: 1, name: 'LA' }
{ _id: 3, name: 'NY' }

Child:
{ _id: 1, _user_id: 1, first_name: 'Little Billy', last_name: 'Gates' }
{ _id: 2, _user_id: 2, first_name: 'Little Stevie', last_name: 'Jobs' }

내가 구현해야 검색이에있다 :

나는 그것을 완수하기 위해 여러 쿼리를 할 필요가 있음을 알고 있지만 어떻게 달성 할 수 있습니까? 맵리 듀스 또는 집계로?

당신은 솔루션에서 제발 포인트?

내가 여기에 그것을 가져 왜 그렇게의 것을, 나는 맵리 듀스를 사용하려했지만 그것은 나를 STATE_ID를 들어 사용자의 문서를 가지고하지 않았다.

해결법

  1. ==============================

    1.MongoDB를 여러 컬렉션에 걸쳐 쿼리를하지 않습니다 - 기간. 여러 컬렉션에서 데이터를 결합해야하는 경우, 여러 쿼리를 수행하여 응용 프로그램 수준에서 그것을 할 수 있습니다.

    MongoDB를 여러 컬렉션에 걸쳐 쿼리를하지 않습니다 - 기간. 여러 컬렉션에서 데이터를 결합해야하는 경우, 여러 쿼리를 수행하여 응용 프로그램 수준에서 그것을 할 수 있습니다.

    이 작업을 수행 할 수있는 것은 오히려 규범보다는 예외해야한다. 당신이 자주 에뮬레이션 필요로 할 때 당신이 나 데이터가 간단하여 MongoDB의 문서 기반 스토리지 개념에 적합되지 않도록 데이터베이스 스키마를 설계 할 때 당신은 아직도 너무 관계형 생각하는 것을 그 중 수단, 그런 식으로 결합합니다.

  2. ==============================

    2.당신은 당신이 스키마 설계에 비정규 접근을하면 이해하기 쉽게 MongoDB를 확인할 수 있습니다. 즉, 당신은 당신의 문서를 요청하는 클라이언트 응용 프로그램을 이해하는 방법을 구성하고 싶습니다. 이는 applicaiton 거래와 도메인 객체로 본질적으로, 당신은 당신의 문서를 모델링하고 있습니다. 당신이 당신의 데이터가이 방법을 모델링 할 때 덜 중요하게 결합한다. 나는 하나의 모음으로 데이터를 비정규 한 방법 고려 :

    당신은 당신이 스키마 설계에 비정규 접근을하면 이해하기 쉽게 MongoDB를 확인할 수 있습니다. 즉, 당신은 당신의 문서를 요청하는 클라이언트 응용 프로그램을 이해하는 방법을 구성하고 싶습니다. 이는 applicaiton 거래와 도메인 객체로 본질적으로, 당신은 당신의 문서를 모델링하고 있습니다. 당신이 당신의 데이터가이 방법을 모델링 할 때 덜 중요하게 결합한다. 나는 하나의 모음으로 데이터를 비정규 한 방법 고려 :

    {  
        _id: 1, 
        first_name: 'Bill', 
        last_name: 'Gates', 
        suburb: 'Suburb A',
        state: 'LA',
        child : [ 3 ]
    }
    
    { 
        _id: 2, 
        first_name: 'Steve', 
        last_name: 'Jobs', 
        suburb: 'Suburb C',
        state 'NY',
        child: [ 4 ] 
    }
    { 
        _id: 3, 
        first_name: 'Little Billy', 
        last_name: 'Gates',
        suburb: 'Suburb A',
        state: 'LA',
        parent : [ 1 ]
    }
    
    {
        _id: 4, 
        first_name: 'Little Stevie', 
        last_name: 'Jobs'
        suburb: 'Suburb C',
        state 'NY',
        parent: [ 2 ]
    }
    

    첫 번째 장점은이 스키마 쿼리보다 훨씬 쉽다는 것이다. 또한, 주소 필드에 대한 업데이트는 필드가 하나의 문서에 포함되기 때문에 각 사람의 실체와 지금은 일치한다. 부모와 자녀 사이의 양방향 관계도 주목? 이는 개별 사용자의 단순한 수집보다이 컬렉션 더 있습니다. 부모 - 자식 관계는이 컬렉션은 또한 소셜 그래프이다 의미한다. 여기에 MongoDB의에서 스키마 설계에 대해 생각할 때 당신에게 도움이 될 수있는 몇 가지 resoures입니다.

  3. ==============================

    3.다음은 현재 데이터베이스의 모든 컬렉션을 통해 검색, 지정된 기준에 일치하는 모든 레코드의 배열을 반환하는 자바 스크립트 함수는 다음과 같습니다

    다음은 현재 데이터베이스의 모든 컬렉션을 통해 검색, 지정된 기준에 일치하는 모든 레코드의 배열을 반환하는 자바 스크립트 함수는 다음과 같습니다

    function searchAll(query,fields,sort) {
        var all = db.getCollectionNames();
        var results = [];
        for (var i in all) {
            var coll = all[i];
            if (coll == "system.indexes") continue;
            db[coll].find(query,fields).sort(sort).forEach(
                function (rec) {results.push(rec);} );
        }
        return results;
    }
    

    몽고 쉘에서, 당신과 같이 호출 다음의 기능을 복사 / 붙여 넣기 할 수 있습니다 :

  4. ==============================

    4.그래서 지금 가입하여 MongoDB에서 가능하며 여기에 $ 조회 및 $면 집계를 사용하여이를 얻을 수 있습니다 아마 여러 컬렉션에서 찾을 수있는 가장 좋은 방법이다

    그래서 지금 가입하여 MongoDB에서 가능하며 여기에 $ 조회 및 $면 집계를 사용하여이를 얻을 수 있습니다 아마 여러 컬렉션에서 찾을 수있는 가장 좋은 방법이다

    db.collection.aggregate([
      { "$limit": 1 },
      { "$facet": {
        "c1": [
          { "$lookup": {
            "from": Users.collection.name,
            "pipeline": [
              { "$match": { "first_name": "your_search_data" } }
            ],
            "as": "collection1"
          }}
        ],
        "c2": [
          { "$lookup": {
            "from": State.collection.name,
            "pipeline": [
              { "$match": { "name": "your_search_data" } }
            ],
            "as": "collection2"
          }}
        ],
        "c3": [
          { "$lookup": {
            "from": State.collection.name,
            "pipeline": [
              { "$match": { "name": "your_search_data" } }
            ],
            "as": "collection3"
          }}
        ]
      }},
      { "$project": {
        "data": {
          "$concatArrays": [ "$c1", "$c2", "$c3" ]
        }
      }},
      { "$unwind": "$data" },
      { "$replaceRoot": { "newRoot": "$data" } }
    ])
    
  5. ==============================

    5.브라이언 - moquin 등 @ 바탕으로, 나는 간단한 키워드로 전체 키 (필드)로 전체 컬렉션을 검색하는 함수의 집합을했다.

    브라이언 - moquin 등 @ 바탕으로, 나는 간단한 키워드로 전체 키 (필드)로 전체 컬렉션을 검색하는 함수의 집합을했다.

    그것은 내 요지에있어; https://gist.github.com/fkiller/005dc8a07eaa3321110b3e5753dda71b

    자세한 내용 들어, 내가 먼저 모든 키를 수집하는 기능을했다.

    function keys(collectionName) {
        mr = db.runCommand({
            'mapreduce': collectionName,
            'map': function () {
                for (var key in this) { emit(key, null); }
            },
            'reduce': function (key, stuff) { return null; },
            'out': 'my_collection' + '_keys'
        });
        return db[mr.result].distinct('_id');
    }
    

    그리고 더 하나는 키 배열에서 $ 또는 쿼리를 생성합니다.

    function createOR(fieldNames, keyword) {
        var query = [];
        fieldNames.forEach(function (item) {
            var temp = {};
            temp[item] = { $regex: '.*' + keyword + '.*' };
            query.push(temp);
        });
        if (query.length == 0) return false;
        return { $or: query };
    }
    

    다음은 하나의 콜렉션을 검색 할 수있는 기능입니다.

    function findany(collection, keyword) {
        var query = createOR(keys(collection.getName()));
        if (query) {
            return collection.findOne(query, keyword);
        } else {
            return false;
        }
    }
    

    그리고 마지막으로 모든 모음에 대한 검색 기능.

    function searchAll(keyword) {
        var all = db.getCollectionNames();
        var results = [];
        all.forEach(function (collectionName) {
            print(collectionName);
            if (db[collectionName]) results.push(findany(db[collectionName], keyword));
        });
        return results;
    }
    

    당신은 단순히 몽고 콘솔에서 모든 기능을로드하고 searchAll ( '키워드')을 실행할 수 있습니다

  6. ==============================

    6.당신은 MongoDB의 드라이버를 사용하여이 $의 mergeObjects을 달성 할 수있다 예 다음의 서류와 컬렉션 주문을 만듭니다

    당신은 MongoDB의 드라이버를 사용하여이 $의 mergeObjects을 달성 할 수있다 예 다음의 서류와 컬렉션 주문을 만듭니다

    db.orders.insert([
      { "_id" : 1, "item" : "abc", "price" : 12, "ordered" : 2 },
      { "_id" : 2, "item" : "jkl", "price" : 20, "ordered" : 1 }
    ])
    

    다음의 서류와 다른 컬렉션 항목을 만듭니다

    db.items.insert([
      { "_id" : 1, "item" : "abc", description: "product 1", "instock" : 120 },
      { "_id" : 2, "item" : "def", description: "product 2", "instock" : 80 },
      { "_id" : 3, "item" : "jkl", description: "product 3", "instock" : 60 }
    ])
    

    다음 작업은 첫 번째 항목 필드를 기준으로 두 컬렉션을 결합하기 위하여 $ 조회 단계를 사용하여 다음 항목과 주문에서 조인 된 문서를 병합 할 $의 replaceRoot에 $ mergeObjects을 사용합니다 :

    db.orders.aggregate([
       {
          $lookup: {
             from: "items",
             localField: "item",    // field in the orders collection
             foreignField: "item",  // field in the items collection
             as: "fromItems"
          }
       },
       {
          $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$fromItems", 0 ] }, "$$ROOT" ] } }
       },
       { $project: { fromItems: 0 } }
    ])
    

    동작은 다음과 같은 문서를 반환합니다 :

    { "_id" : 1, "item" : "abc", "description" : "product 1", "instock" : 120, "price" : 12, "ordered" : 2 }
    { "_id" : 2, "item" : "jkl", "description" : "product 3", "instock" : 60, "price" : 20, "ordered" : 1 }
    

    이 기술을 병합 개체와 결과를 반환

  7. from https://stackoverflow.com/questions/20056903/search-on-multiple-collections-in-mongodb by cc-by-sa and MIT license