লিনক থেকে এসকিএল এলোমেলো সারি


112

আমার যখন শর্ত রয়েছে তখন লিনক থেকে এসকিউএল ব্যবহার করে এলোমেলো সারিটি পুনরুদ্ধার করার সর্বোত্তম (এবং দ্রুততম) উপায় কী, উদাহরণস্বরূপ কিছু ক্ষেত্র সত্য হতে হবে?


আপনি সত্যিকারের শর্তাদি পরীক্ষা করে ক্রম করার জন্য আপনার কাছে দুটি বিকল্প রয়েছে। যদি সত্যিকারের শর্তটি বেশিরভাগ আইটেমগুলিতে ঘটে তবে কেবল একটি এলোমেলো আইটেম ধরুন তবে পরীক্ষা করে মিথ্যা হিসাবে পুনরাবৃত্তি করুন। যদি বিরল হয়ে থাকে তবে ডাটাবেসটি অপশনগুলিকে সত্য অবস্থার মধ্যে সীমাবদ্ধ রাখুন এবং তারপরে এলোমেলোভাবে একটি ধরুন grab
রেক্স লোগান

1
যেমন এই সাইটে প্রচুর উত্তর রয়েছে - দ্বিতীয়-রেটযুক্ত গৃহীতটির চেয়ে অনেক ভাল।
নিকিবি 3ro

উত্তর:


169

আপনি এটি একটি নকল ইউডিএফ ব্যবহার করে ডাটাবেসে করতে পারেন; আংশিক শ্রেণিতে, ডেটা প্রসঙ্গে একটি পদ্ধতি যুক্ত করুন:

partial class MyDataContext {
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}

তারপরে ঠিক order by ctx.Random(); এটি এসকিউএল-সার্ভার সৌজন্যে এলোমেলোভাবে অর্ডার করবে NEWID()। অর্থাত

var cust = (from row in ctx.Customers
           where row.IsActive // your filter
           orderby ctx.Random()
           select row).FirstOrDefault();

মনে রাখবেন এটি কেবলমাত্র ছোট থেকে মাঝের আকারের টেবিলের জন্য উপযুক্ত; বিশাল টেবিলগুলির জন্য, এটি সার্ভারে একটি কার্যকারিতা প্রভাব ফেলবে এবং সারিগুলির সংখ্যা ( Count) সন্ধান করতে এটি আরও দক্ষ হবে , তারপরে এলোমেলোভাবে একটি বেছে নিন ( Skip/First)।


গণনা পদ্ধতির জন্য:

var qry = from row in ctx.Customers
          where row.IsActive
          select row;

int count = qry.Count(); // 1st round-trip
int index = new Random().Next(count);

Customer cust = qry.Skip(index).FirstOrDefault(); // 2nd round-trip

3
যদি এটি ফিল্টার পরে 30k হয় , আমি না বলব: এই পদ্ধতির ব্যবহার করবেন না। 2 রাউন্ড-ট্রিপ করুন; 1 টি গণনা পেতে (), এবং 1 পেতে এলোমেলো সারি ...
মার্ক গ্র্যাভেল

1
আপনি যদি পাঁচটি (বা "x") এলোমেলো সারি চান? ছয় রাউন্ড-ট্রিপগুলি করা কি সেরা বা কোনও সঞ্চিত পদ্ধতিতে এটি কার্যকর করার কোনও সুবিধাজনক উপায় নেই?
নিল স্ট্যুবলেন

2
@ নিল এস: সিটিএক্স.র্যান্ডম () দ্বারা প্রাপ্ত আদেশটি টেক (5) এর সাথে মেশানো যেতে পারে; তবে আপনি যদি গণনা () পদ্ধতির ব্যবহার করছেন তবে আমি আশা করি round রাউন্ড ট্রিপগুলি সহজ বিকল্প।
মার্ক গ্রাভেল

1
System.Data.Linq বা System.Data.Linq.Mapping.Function এট্রিবিউটটি কাজ করবে না এমন একটি রেফারেন্স যুক্ত করতে ভুলবেন না।
জাগুইর

8
আমি জানি এটি পুরানো, তবে আপনি যদি একটি বৃহত টেবিল থেকে অনেক এলোমেলো সারি নির্বাচন করে থাকেন তবে এটি দেখুন: এমএসডিএন.মাইক্রোসফটকম /en-us/library/cc441928.aspx লিনকু সমতুল্য কিনা তা আমি জানি না if
jwd

60

সত্তা ফ্রেমওয়ার্কের জন্য অন্য একটি নমুনা:

var customers = db.Customers
                  .Where(c => c.IsActive)
                  .OrderBy(c => Guid.NewGuid())
                  .FirstOrDefault();

এটি লিনকিউ থেকে এসকিউএল নিয়ে কাজ করে না। OrderByকেবল বাদ করা হচ্ছে।


4
আপনি কি এটি প্রোফাইল করেছেন এবং নিশ্চিত হয়েছিলেন যে এটি কাজ করে? লিনকিউপ্যাড ব্যবহার করে আমার পরীক্ষাগুলিতে, ধারা অনুসারে ক্রমটি বাদ দেওয়া হচ্ছে।
জিম উলি

এটিই এই সমস্যার সর্বোত্তম সমাধান
12 থাইলেজাররা

8
এটি লিনকিউ থেকে এসকিউএল তে কাজ করে না ... সম্ভবত এটি সত্ত্বা ফ্রেমওয়ার্ক 4 এ কাজ করে (এটি নিশ্চিত করে না)। আপনি কেবলমাত্র .আর্ডার বাই নির্দেশিকা দিয়ে যদি আপনি একটি তালিকা বাছাই করে থাকেন ... ডিবি দিয়ে এটি কাজ করবে না।
নকিব 3

2
এটি শেষ পর্যন্ত নিশ্চিত করতে যে এটি EF4 এ কাজ করে - এটি ক্ষেত্রে দুর্দান্ত বিকল্প।
নিকিব 3 ই

1
আপনি কি নিজের উত্তরটি সম্পাদনা করতে এবং ব্যাখ্যা করতে পারবেন যে কোনও নতুন গাইডের সাথে অর্ডার বাই কৌশলটি কেন করে? উপায় দ্বারা দুর্দান্ত উত্তর :)
জিন-ফ্রান্সোয়েস Côté

32

সম্পাদনা: আমি কেবলমাত্র এটি লক্ষ্য করেছি এটি এসকিউএল থেকে লিনিক, অবজেক্টে লিনকিউ নয়। আপনার জন্য এটি করতে ডাটাবেস পেতে মার্কের কোডটি ব্যবহার করুন। আমি এই উত্তরটি অবজেক্টগুলিতে লিনকুইয়ের আগ্রহের পয়েন্ট হিসাবে এখানে রেখেছি।

আশ্চর্যজনকভাবে যথেষ্ট, আপনার আসলে গণনা পাওয়ার দরকার নেই। তবে আপনাকে গণনা না পাওয়া পর্যন্ত প্রতিটি উপাদান আনতে হবে।

আপনি যা করতে পারেন তা হ'ল "বর্তমান" মান এবং বর্তমান গণনা সম্পর্কে ধারণা রাখা। আপনি যখন পরবর্তী মানটি আনবেন তখন একটি এলোমেলো নম্বর নিন এবং "বর্তমান "টিকে" নতুন "সাথে 1 / n এর সম্ভাব্যতার সাথে প্রতিস্থাপন করুন যেখানে n গণনা।

সুতরাং আপনি যখন প্রথম মানটি পড়েন, আপনি সর্বদা এটি "বর্তমান" মানটি তৈরি করেন। আপনি যখন দ্বিতীয় মানটি পড়েন, আপনি এটি করতে পারেন যে বর্তমান মান (সম্ভাব্যতা 1/2)। আপনি যখন তৃতীয় মানটি পড়েন তখন আপনি এটি করতে পারেন যে বর্তমান মান (সম্ভাব্যতা ১/৩) ইত্যাদি data

একটি শর্ত সহ এটি প্রয়োগ করতে, শর্তটি পূরণ করে না এমন কিছু উপেক্ষা করুন। এটির সবচেয়ে সহজ উপায় হ'ল প্রথমে একটি ক্লজ প্রয়োগ করে শুরু করার জন্য কেবল "ম্যাচিং" ক্রমটি বিবেচনা করা।

এখানে একটি দ্রুত বাস্তবায়ন। আমি মনে করি এটি ঠিক আছে ...

public static T RandomElement<T>(this IEnumerable<T> source,
                                 Random rng)
{
    T current = default(T);
    int count = 0;
    foreach (T element in source)
    {
        count++;
        if (rng.Next(count) == 0)
        {
            current = element;
        }            
    }
    if (count == 0)
    {
        throw new InvalidOperationException("Sequence was empty");
    }
    return current;
}

4
এফওয়াইআই - আমি একটি দ্রুত চেক চালিয়েছি এবং এই ফাংশনটিতে অভিন্ন সম্ভাবনা বন্টন রয়েছে (বর্ধনশীল গণনাটি মূলত ফিশার-ইয়েটস সাফল্যের মতো একই ব্যবস্থা তাই এটি হওয়া উচিত যুক্তিযুক্ত বলে মনে হয়)।
গ্রেগ বিচ

@ গ্রেগ: শীতল, ধন্যবাদ এটি আমার কাছে দ্রুত চেক সহকারে ভাল লাগছিল, তবে এই জাতীয় কোডটিতে একের পর এক ত্রুটি পাওয়া এত সহজ। লিনকিউ থেকে এসকিউএল অবশ্যই কার্যত অপ্রাসঙ্গিক তবে তবুও দরকারী।
জন স্কিটি

@JonSkeet, হাই, আপনি না পরীক্ষা করতে এই এবং আমাকে আমি অনুপস্থিত am দিন
shaijut

@ টাইলারলাইং: না, এখানে বিরতি বোঝানো হয়নি। প্রথম পুনরাবৃত্তির অন, currentহবে সবসময় প্রথম উপাদান সেট করা। দ্বিতীয় পুনরাবৃত্তিতে, একটি 50% পরিবর্তন রয়েছে যে এটি দ্বিতীয় উপাদানটিতে সেট করা হবে। তৃতীয় পুনরাবৃত্তিতে, এটির তৃতীয় উপাদানটিতে সেট করার 33% সুযোগ রয়েছে। ব্রেক স্টেটমেন্ট যুক্ত করার অর্থ হ'ল আপনি প্রথম উপাদানটি পড়ার পরে সর্বদা প্রস্থান করবেন এবং একেবারেই এলোমেলো নয় making
জন স্কিটি

@ জোনস্কিট দোহ! আমি আপনার গণনার ব্যবহার ভুল করে পড়েছি (যেমন ভেবেছিলাম এটি নি-র মতো এলোমেলো পরিসরের সাথে ফিশার-ইয়েটস স্টাইল)। তবে ফিশার-ইয়েটসে প্রথম উপাদানটি নির্বাচন করার জন্য কোনও উপাদানকে মোটামুটি পছন্দ করা। তবে এর জন্য উপাদানগুলির মোট সংখ্যা জানতে হবে। আমি এখন দেখতে পাচ্ছি যে আপনার সমাধানটি কোনও আইনিউমারেবলের জন্য ঝরঝরে the বরং এটি একটি পাসে সলভ করে, যেমন আপনি বলেছিলেন: "আপনি গণনা না পাওয়া পর্যন্ত প্রতিটি উপাদান আনতে হবে"।
টাইলার প্রয়াস

19

দক্ষতার সাথে অর্জন করার একটি উপায় হ'ল আপনার ডেটাতে একটি কলাম যুক্ত করা Shuffleযা এলোমেলো ইনট দ্বারা জনবহুল হয় (প্রতিটি রেকর্ড তৈরি হওয়ার সাথে সাথে)।

এলোমেলো ক্রমে টেবিলটি অ্যাক্সেস করতে আংশিক কোয়েরিটি হ'ল ...

Random random = new Random();
int seed = random.Next();
result = result.OrderBy(s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);

এটি ডাটাবেসে একটি এক্সওর অপারেশন করে এবং সেই এক্সওরটির ফলাফল অনুসারে অর্ডার দেয়।

সুবিধাদি:-

  1. দক্ষ: এসকিউএল অর্ডার পরিচালনা করে, পুরো টেবিলটি আনার দরকার নেই
  2. পুনরাবৃত্তিযোগ্য: (পরীক্ষার জন্য ভাল) - একই র্যান্ডম ক্রম উত্পন্ন করতে একই এলোমেলো বীজ ব্যবহার করতে পারে

এটি আমার হোম অটোমেশন সিস্টেমটি প্লেলিস্টগুলি এলোমেলো করে জানাতে ব্যবহার করে। এটি প্রতিদিন একটি নতুন বীজ বাছাই করে দিনের সময় একটি সামঞ্জস্যপূর্ণ অর্ডার দেয় (সহজ বিরতি / পুনরায় জীবনযাত্রার সক্ষমতার অনুমতি দেয়) তবে প্রতিটি নতুন দিন প্রতিটি প্লেলিস্টে একটি নতুন চেহারা।


এলোমেলোভাবে কী প্রভাব ফেলতে পারে যদি আপনি কেবলমাত্র একটি বিদ্যমান অটো-ইনক্রিমিং পরিচয় ক্ষেত্রটি ব্যবহার করেন (বীজ স্পষ্টত এলোমেলো থাকবে)? এছাড়াও - টেবিলের রেকর্ড সংখ্যার সমান এএ সহ একটি বীজ মান কি পর্যাপ্ত বা এটি বেশি হওয়া উচিত?
ব্রায়ান

সম্মত, এটি একটি দুর্দান্ত উত্তর যা আইএমওর আরও বেশি পদক্ষেপ নেওয়া উচিত। আমি এটি একটি অ্যান্টিটি ফ্রেমওয়ার্ক ক্যোয়ারিতে ব্যবহার করেছি এবং বিটওয়াইস-এক্সআরআর অপারেটর-পরিস্থিতিটি কিছুটা পরিস্কার করার জন্য সরাসরি কাজ করছে বলে মনে হচ্ছে: result = result.OrderBy(s => s.Shuffle ^ seed);(যেমন ~, এবং এবং অপারেটরগুলির মাধ্যমে এক্সওআর বাস্তবায়ন করার প্রয়োজন নেই)।
স্টিভেন র্যান্ডস

7

আপনি যদি var count = 16টেবিল থেকে উদাহরণস্বরূপ এলোমেলো সারি পেতে চান তবে আপনি লিখতে পারেন

var rows = Table.OrderBy(t => Guid.NewGuid())
                        .Take(count);

এখানে আমি ইএফ ব্যবহার করেছি, এবং সারণীটি একটি ডিবিসেট


1

যদি এলোমেলো সারিগুলি পাওয়ার নমুনা হয় তবে আমি এখানে খুব সংক্ষেপে কথা বললাম লারসন এট আল। মাইক্রোসফ্ট রিসার্চ টিমের একটি দুর্দান্ত পদ্ধতির বিষয়ে যেখানে তারা বস্তুগত দৃষ্টিভঙ্গি ব্যবহার করে স্কেল সার্ভারের জন্য একটি নমুনা কাঠামো তৈরি করেছে। প্রকৃত কাগজের সাথে একটি লিঙ্কও রয়েছে।


1
List<string> lst = new List<string>();
lst.Add("Apple"); 
lst.Add("Guva");
lst.Add("Graps"); 
lst.Add("PineApple");
lst.Add("Orange"); 
lst.Add("Mango");

var customers = lst.OrderBy(c => Guid.NewGuid()).FirstOrDefault();

ব্যাখ্যা: গাইড সন্নিবেশ করা (যা এলোমেলো) অর্ডারবাই সহ অর্ডারটি এলোমেলো হবে।


গাইডগুলি "এলোমেলো" নয় তারা অ-অনুক্রমিক। পার্থক্য আছে. অনুশীলনে সম্ভবত এটি তুচ্ছ কিছু হিসাবে গুরুত্বপূর্ণ নয়।
ক্রিস মেরিসিক

0

এখান থেকে অল্প সংখ্যক কয়েকটি র্যান্ডম পেজ কীভাবে পাবেন তা ভাবতে ভাবতে এখানে এসেছিলেন, সুতরাং প্রতিটি ব্যবহারকারীর কিছু আলাদা র্যান্ডম 3 পৃষ্ঠা পাওয়া যায়।

এটি আমার চূড়ান্ত সমাধান, শেয়ারপয়েন্ট ২০১০-এর পৃষ্ঠাগুলির তালিকার বিরুদ্ধে লিনকুইয়ের সাথে খোঁজখবর নিচ্ছেন। এটি ভিজ্যুয়াল বেসিকের মধ্যে রয়েছে, দুঃখিত: পি

Dim Aleatorio As New Random()

Dim Paginas = From a As SPListItem In Sitio.RootWeb.Lists("Páginas") Order By Aleatorio.Next Take 3

সম্ভবত প্রচুর ফলাফল জিজ্ঞাসা করার আগে কিছুটা প্রোফাইলিং করা উচিত, তবে এটি আমার উদ্দেশ্যটির জন্য উপযুক্ত


0

DataTableএর বিপরীতে আমার কাছে এলোমেলো ফাংশন ক্যোয়ারী রয়েছে :

var result = (from result in dt.AsEnumerable()
              order by Guid.NewGuid()
              select result).Take(3); 

0

নীচের উদাহরণটি উত্সটিকে একটি গণনা পুনরুদ্ধার করতে কল করবে এবং তারপরে 0 এবং n এর মধ্যে একটি সংখ্যার সাথে উত্সটিতে একটি স্কিপ এক্সপ্রেশন প্রয়োগ করবে। দ্বিতীয় পদ্ধতিটি এলোমেলো বস্তু (যা মেমরিতে সমস্ত কিছু অর্ডার করবে) ব্যবহার করে আদেশ প্রয়োগ করবে এবং পদ্ধতি কলটিতে পাস নম্বরটি নির্বাচন করবে।

public static class IEnumerable
{
    static Random rng = new Random((int)DateTime.Now.Ticks);

    public static T RandomElement<T>(this IEnumerable<T> source)
    {
        T current = default(T);
        int c = source.Count();
        int r = rng.Next(c);
        current = source.Skip(r).First();
        return current;
    }

    public static IEnumerable<T> RandomElements<T>(this IEnumerable<T> source, int number)
    {
        return source.OrderBy(r => rng.Next()).Take(number);
    }
}

কিছু ব্যাখ্যা চমৎকার হবে
অ্যান্ড্রু বারবার

এই কোডটি থ্রেডসেফ নয় এবং কেবল একক থ্রেডেড কোডে ব্যবহার করা যেতে পারে (সুতরাং এএসপি
ডট

0

আমি এলোমেলো সংবাদ এবং এর কাজ সূক্ষ্ম গ্রহণের জন্য এই পদ্ধতিটি ব্যবহার করি;)

    public string LoadRandomNews(int maxNews)
    {
        string temp = "";

        using (var db = new DataClassesDataContext())
        {
            var newsCount = (from p in db.Tbl_DynamicContents
                             where p.TimeFoPublish.Value.Date <= DateTime.Now
                             select p).Count();
            int i;
            if (newsCount < maxNews)
                i = newsCount;
            else i = maxNews;
            var r = new Random();
            var lastNumber = new List<int>();
            for (; i > 0; i--)
            {
                int currentNumber = r.Next(0, newsCount);
                if (!lastNumber.Contains(currentNumber))
                { lastNumber.Add(currentNumber); }
                else
                {
                    while (true)
                    {
                        currentNumber = r.Next(0, newsCount);
                        if (!lastNumber.Contains(currentNumber))
                        {
                            lastNumber.Add(currentNumber);
                            break;
                        }
                    }
                }
                if (currentNumber == newsCount)
                    currentNumber--;
                var news = (from p in db.Tbl_DynamicContents
                            orderby p.ID descending
                            where p.TimeFoPublish.Value.Date <= DateTime.Now
                            select p).Skip(currentNumber).Take(1).Single();
                temp +=
                    string.Format("<div class=\"divRandomNews\"><img src=\"files/1364193007_news.png\" class=\"randomNewsImg\" />" +
                                  "<a class=\"randomNews\" href=\"News.aspx?id={0}\" target=\"_blank\">{1}</a></div>",
                                  news.ID, news.Title);
            }
        }
        return temp;
    }

0

লিনিকিউপ্যাডে লিনকিউ থেকে এসকিউএল ব্যবহার করা সি # স্টেটমেন্টের মতো দেখায়

IEnumerable<Customer> customers = this.ExecuteQuery<Customer>(@"SELECT top 10 * from [Customers] order by newid()");
customers.Dump();

উত্পন্ন এসকিউএল হ'ল

SELECT top 10 * from [Customers] order by newid()

0

আপনি যদি লিনকিউপ্যাড ব্যবহার করেন , সি # প্রোগ্রাম মোডে স্যুইচ করুন এবং এইভাবে করুন:

void Main()
{
    YourTable.OrderBy(v => Random()).FirstOrDefault.Dump();
}

[Function(Name = "NEWID", IsComposable = true)]
public Guid Random()
{
    throw new NotImplementedException();
}


0

মার্ক গ্র্যাভেলের দ্রবণে যোগ করতে। যদি আপনি নিজেই ড্যাটাকনটেক্সট ক্লাসের সাথে কাজ করছেন না (কারণ আপনি এটি পরীক্ষার উদ্দেশ্যে কোনওভাবে উদাহরণস্বরূপ ডেটাঅন্টেক্সটকে নকল করে), আপনি সংজ্ঞায়িত ইউডিএফ সরাসরি ব্যবহার করতে পারবেন না: এটি এসকিউএলে সংকলিত হবে না কারণ আপনি এটি কোনওতে ব্যবহার করছেন না আপনার প্রকৃত ডেটা প্রসঙ্গ শ্রেণীর সাবক্লাস বা আংশিক বর্গ।

এই সমস্যাটির সমাধানের জন্য হ'ল আপনার প্রক্সিটিতে একটি র্যান্ডমাইজ ফাংশন তৈরি করা, আপনি যে প্রশ্নটি এলোমেলো করে রাখতে চান তা দিয়ে এটি খাওয়ানো:

public class DataContextProxy : IDataContext
{
    private readonly DataContext _context;

    public DataContextProxy(DataContext context)
    {
        _context = context;
    }

    // Snipped irrelevant code

    public IOrderedQueryable<T> Randomize<T>(IQueryable<T> query)
    {
        return query.OrderBy(x => _context.Random());
    }
}

আপনি আপনার কোডটিতে এটি কীভাবে ব্যবহার করবেন তা এখানে রয়েছে:

var query = _dc.Repository<SomeEntity>();
query = _dc.Randomize(query);

সম্পূর্ণ হওয়ার জন্য, এটি FAKE ডেটাঅন্টেক্সটে (যা মেমরি সত্তায় ব্যবহার করে) এটি প্রয়োগ করতে হয়:

public IOrderedQueryable<T> Randomize<T>(IQueryable<T> query)
{
    return query.OrderBy(x => Guid.NewGuid());
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.